我希望得到一个编译时数组,所以来this answer。以下是答案中的代码:
#include <array>
#include <algorithm>
#include <iterator>
#include <iostream>
template<int ...>
struct seq { };
template<int N, int ...S>
struct gens : gens<N-1, N-1, S...> { };
template<int ...S>
struct gens<0, S...> {
typedef seq<S...> type;
};
constexpr int f(int n) {
return n;
}
template <int N>
class array_thinger {
typedef typename gens<N>::type list;
template <int ...S>
static constexpr std::array<int,N> make_arr(seq<S...>) {
return std::array<int,N>{{f(S)...}};
}
public:
static constexpr std::array<int,N> arr = make_arr(list());
};
template <int N>
constexpr std::array<int,N> array_thinger<N>::arr;
int main() {
std::copy(begin(array_thinger<10>::arr), end(array_thinger<10>::arr),
std::ostream_iterator<int>(std::cout, "\n"));
}
但我是元编程的新手,所以这里有两个问题:
struct gens : gens<N-1, N-1, S...>
的语法是什么?它似乎是c ++ 0x中的Delegating constructors
,但我不确定。 struct seq
和typedef seq<S...> type
的用法是什么?啊,我也没有很好的模板命令。 答案 0 :(得分:1)
你所拥有的是一个以递归方式自我调用的模板。
如果你写:
gens<3>::type
它使用您的模板
template<int N, int ...S>
struct gens : gens<N-1, N-1, S...> { };
因为N变为3而S中的参数为无。模板结构本身派生自gens<N-1, N-1, S...>
,然后变为gens<2,2>
。这将再次调用(递归!)本身。
因此,使用N = 2调用gens模板,S是一个包含一个int的元素的列表:2。再次调用gens
,现在使用`gens&lt; 1,1,2&gt;。< / p>
重复,直到N变为0.现在,由于gens的专业化:
template<int ...S>
struct gens<0, S...> {
typedef seq<S...> type;
};
将调用此专业化。所以这里我们得到gens&lt; 0,0,1,2&gt;。所以N是0而S是0,1,2的列表。现在模板生成类型type
。类型现在是seq&lt; 0,1,2&GT;
当gens从自身递归递归时,你可以从该继承序列中获取类型,因为0的特化是结构的根。
所以你可以写:
gens<3>::type
是:seq<0,1,2>