我希望获得一个编译时数组,因此请进入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
的用法是什么?啊,我对模板也没有好命令。 最佳答案
您所拥有的是一个模板,该模板以递归方式将其称为自身。
如果您写:
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 。重复直到N变为0。现在,由于gen的特殊化:
template<int ...S>
struct gens<0, S...> {
typedef seq<S...> type;
};
这个专业将被称为。所以在这里我们得到gens 。因此N为0,S为0,1,2的列表。现在,模板生成类型
type
。现在,类型为seq 。当gens从其自身派生递归时,您可以从该继承序列中获取类型,因为0的特殊化是该结构的根。
所以你可以这样写:
gens<3>::type
这是:
seq<0,1,2>