作为练习,我正在尝试编写两个简单的函数,将非类型模板转换为N. 第一个需要创建一个元组,其中包含一些类型为T的对象的N个副本。我希望它类似于以下内容:
template <class T, int N>
constexpr std::tuple<T...> fun(T t) {
return (N > 0) ? std::tuple_cat(t, fun<T, N-1>(t)) : std::make_tuple(t);
}
我也试过这样的事情失败了(http://liveworkspace.org/code/3LZ0Fe)。 我希望能够用T = bool实例化它,比如说:
auto bools = fun<bool, 10> (false);
第二个应该是轻微的变化;我有一个模板化的结构Foo,我想创建一个包含Foo&lt;的元组。 0&gt;,...,Foo&lt; N>
template <int N> struct Foo {
static const int id = N;
}
template <template <int> class T, int N>
constexpr ??? fun2 (???) {...}
由于模板化函数不能部分专门化,我甚至不知道如何为递归编写正确的终止。 我想完全静态地执行此操作,而不使用 for 循环。
=============================================== ===================================
按照Seth的建议,我一直坚持编写有趣的函数本身无限递归:
template<typename T, int N>
typename fun_helper<T, N>::type
fun(T t) {
if (N > 0)
return typename fun_helper<T, N>::type
{ std::tuple_cat(std::make_tuple(t), fun<T, N-1>(t)) };
else return typename fun_helper<T, N>::type { };
}
通过使用带终止的附加结构,我能够实现这一点:
template<typename T, int N> struct fun {
typename fun_helper<T, N>::type make(T t) {
return typename fun_helper<T, N>::type
{ std::tuple_cat(std::make_tuple(t), fun<T, N-1>().make(t)) };
}
};
template<typename T> struct fun<T, 0> {
typename fun_helper<T, 0>::type
make(T t) {
return typename fun_helper<T, 0>::type { };
}
};
电话仍然相对笨拙:
auto conds = fun<bool, 3>().make(false);
如果没有这个额外的结构,有没有办法让它工作?
auto conds = fun<bool, 3>(false);
答案 0 :(得分:1)
对于第一个,您可以使用struct
递归构建参数包以进行部分特化(我以这种方式向您展示,因为它与#2相关)。此代码未经过测试,不会处理元素的默认值,但它可以为您提供想法,并且可以轻松添加默认值代码。
template<typename T, int N, typename... Rest>
struct fun_helper {
typedef typename fun_helper<T, N - 1, T, Rest...>::type type;
};
template<typename T, typename... Rest>
struct fun_helper<T, 0, Rest...> {
typedef std::tuple<Rest...> type;
};
template<typename T, int N>
typename fun_helper<T, N>::type fun() {
return typename fun_helper<T, N>::type { };
}
对于第二种,您可以将上述技术与int
s的参数包结合使用,并使用...
展开它们,如
Foo<Ints>...
扩展为
Foo<Int1>, Foo<Int2>, ...
在你的功能中。