我希望获得一个编译时数组,因此请进入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 seqtypedef 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>

10-07 21:51