当函数 returns 由模板类型和另一个类型组成的类型时模板参数推导
Template argument deduction when the function returns a type composed from the template type and another
这个标题很难用文字表达,但这是我在 non-compileable 代码中试图实现的:
template<template <typename> class Container>
Container<int> foo() {
return Container<int>{1,2,3};
}
int main() {
auto bar = foo<std::vector>();
return 0;
}
基本上我想要一个模板函数,它可以 "compose" 其 return 类型来自传递给它的类型和先前已知的类型(在本例中为 int
)。在这种情况下,我想要一个 returns 调用者指定的容器内的任意数据类型的函数。 (我所说的任意并不是指在编译时随机或未确定,而是调用者没有 "input" 关于数据类型是什么,这是在函数本身内部确定的。
这种类型的事情甚至可以通过 std+1z 的 clang 或 gcc 实现吗?我错过了一些非常明显的东西吗?是否有我不知道的跨越数百个字符的“1 行”解决方案?
我在这里看到过各种类似的例子,但它们似乎都假定函数将指针或引用作为参数并填充到这些容器中。
你唯一的麻烦是 std::vector
是 而不是 和 template <typename> class
。它是一个template <typename T, typename Alloc> class
,恰好有第二个模板参数的默认参数。
解决这个问题的一种方法是使用一个真正只接受一个参数的别名模板:
#include <vector>
template<template <typename> class Container>
Container<int> foo() {
return Container<int>{1,2,3};
}
template <typename T>
using Vec = std::vector<T>;
int main() {
auto bar = foo<Vec>();
return 0;
}
评论中推荐的另一种方法是在声明原始函数的模板时使用可变类型名,它接受任何 class 仅采用类型参数的模板。然后你可以只用一个参数实例化它,因为实际模板有第二个默认值。这适用于 C++11 及更高版本。
#include <vector>
template<template <typename...> class Container>
Container<int> foo() {
return Container<int>{1,2,3};
}
int main() {
auto bar = foo<std::vector>();
return 0;
}
带有typename...
模板模板参数列表的模板模板参数将绑定到任何模板名称,无论实际模板参数 计数。您可以使用它并推测模板可以使用单个参数实例化。
template<template <typename...> class Container>
Container<int> foo() {
return Container<int>{1,2,3};
}
int main() {
auto bar = foo<std::vector>();
return 0;
}
据我所知,这从 C++-11
开始就有效。
也可以使用单个参数声明模板化别名,使界面更加自文档化
template<template <typename> class Container>
Container<int> foo() {
return Container<int>{1,2,3};
}
template<typename T> using vector_container = std::vector<T>;
int main() {
auto bar = foo<vector_container>();
return 0;
}
这个标题很难用文字表达,但这是我在 non-compileable 代码中试图实现的:
template<template <typename> class Container>
Container<int> foo() {
return Container<int>{1,2,3};
}
int main() {
auto bar = foo<std::vector>();
return 0;
}
基本上我想要一个模板函数,它可以 "compose" 其 return 类型来自传递给它的类型和先前已知的类型(在本例中为 int
)。在这种情况下,我想要一个 returns 调用者指定的容器内的任意数据类型的函数。 (我所说的任意并不是指在编译时随机或未确定,而是调用者没有 "input" 关于数据类型是什么,这是在函数本身内部确定的。
这种类型的事情甚至可以通过 std+1z 的 clang 或 gcc 实现吗?我错过了一些非常明显的东西吗?是否有我不知道的跨越数百个字符的“1 行”解决方案?
我在这里看到过各种类似的例子,但它们似乎都假定函数将指针或引用作为参数并填充到这些容器中。
你唯一的麻烦是 std::vector
是 而不是 和 template <typename> class
。它是一个template <typename T, typename Alloc> class
,恰好有第二个模板参数的默认参数。
解决这个问题的一种方法是使用一个真正只接受一个参数的别名模板:
#include <vector>
template<template <typename> class Container>
Container<int> foo() {
return Container<int>{1,2,3};
}
template <typename T>
using Vec = std::vector<T>;
int main() {
auto bar = foo<Vec>();
return 0;
}
评论中推荐的另一种方法是在声明原始函数的模板时使用可变类型名,它接受任何 class 仅采用类型参数的模板。然后你可以只用一个参数实例化它,因为实际模板有第二个默认值。这适用于 C++11 及更高版本。
#include <vector>
template<template <typename...> class Container>
Container<int> foo() {
return Container<int>{1,2,3};
}
int main() {
auto bar = foo<std::vector>();
return 0;
}
带有typename...
模板模板参数列表的模板模板参数将绑定到任何模板名称,无论实际模板参数 计数。您可以使用它并推测模板可以使用单个参数实例化。
template<template <typename...> class Container>
Container<int> foo() {
return Container<int>{1,2,3};
}
int main() {
auto bar = foo<std::vector>();
return 0;
}
据我所知,这从 C++-11
开始就有效。
也可以使用单个参数声明模板化别名,使界面更加自文档化
template<template <typename> class Container>
Container<int> foo() {
return Container<int>{1,2,3};
}
template<typename T> using vector_container = std::vector<T>;
int main() {
auto bar = foo<vector_container>();
return 0;
}