如何使用构造函数的参数构造成员数组的每个元素

rit*_*ter 3 c++ templates c++11

可能重复:
将std :: tuple转换为std :: array C++ 11

假设你有:

template<class T,int N>
struct A {
  A(const B& b): /* what comes here */ {}

  std::array<T,N> F;
};
Run Code Online (Sandbox Code Playgroud)

F[]在上面的例子中,我需要使用构造函数的参数构造每个元素b.这很棘手,因为参数可能不是可以是编译时常量的类型,例如int等等.

这不同于是否可以根据整数模板参数构造成员数组的元素?因为这里使用了用户定义的结构,因此我们需要它的运行时副本.

Xeo*_*Xeo 8

索引技巧也可以在这里应用,你只需要稍微改造一下:

template <std::size_t... Is>
struct indices {};

template <std::size_t N, std::size_t... Is>
struct build_indices
  : build_indices<N-1, N-1, Is...> {};

template <std::size_t... Is>
struct build_indices<0, Is...> : indices<Is...> {};

template<class T,int N>
struct A {
  template<std::size_t... Is>
  A(const B& b, indices<Is...>) : F{{(void(Is),b)...}} {}
  A(const B& b) : A(b, build_indices<N>{}) {}

  std::array<T,N> F;
};
Run Code Online (Sandbox Code Playgroud)

实例.

我们基本上忽略了索引的值,只使用包本身来执行扩展,即只有包的大小才是我们感兴趣的.重复使用索引似乎是滥用,因为我们对实际值不感兴趣,但我认为重复使用这些机制很好.创建N-element包的任何其他构造看起来都是一样的,除了包很可能只包含零.

  • 我不得不盯着代码一段时间才弄明白.`(Is)...`将按顺序分别为每个'N`参数.`(void(Is))......`将是'N`空洞.`(void(Is),B)`是'B`.所以`(void(Is),B)..`是`N`对应的'B`对象!:D很棒! (2认同)