c++ - 关于元编程的几个问题?

标签 c++ templates metaprogramming

希望得到一个编译时数组,所以来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"));
}

但是我是元编程的新手,所以这里有两个问题:

  1. struct gens : gens<N-1, N-1, S...> 的语法是什么? ?好像Delegating constructors在 c++0x 中,但我不确定。
  2. 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> .这将再次调用(递归!)自身。

所以 gens 模板用 N=2 调用,S 是一个列表,其中一个元素包含一个 int : 2。这再次调用 gens , 现在有 `gens<1,1,2>.

重复直到 N 变为 0。现在,由于氏族的特化:

template<int ...S>
    struct gens<0, S...> {
    typedef seq<S...> type;
};

这个专业将被调用。所以这里我们得到gens<0,0,1,2>。所以 N 是 0,S 是 0,1,2 的列表。现在模板生成类型 type .类型现在是 seq<0,1,2>。

由于 gens 从自身递归派生,您可以从该继承序列中获取类型,因为 0 的特化是结构的根。

所以你可以这样写:

 gens<3>::type

即:seq<0,1,2>

关于c++ - 关于元编程的几个问题?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47427421/

相关文章:

templates - Ansible 取消保管和模板化文件

c++ - 如何重载不接受或不返回 ostream 的运算符 <<

c++ - 将与谓词匹配的相邻元组元素分组为子元组

c++ - 使用远程线程的 DLL 注入(inject)在执行时不执行任何操作

C++20 NTTP 特化

c++ - TCP 库正在捆绑消息?

c++ - 如何实现 is_enum_class 类型特征?

ruby - 为方法名动态生成前缀

c++ - Qt中带有子菜单的可点击菜单项

c++ - 如何检查C中随机数列表中的元素