【问题标题】:Is it possible to construct the elements of a member array depending on an integral template parameter?是否可以根据完整的模板参数构造成员数组的元素?
【发布时间】:2012-10-01 22:46:59
【问题描述】:

假设:

template<class T,int N>
struct A {
  A(): /* here */ {}

  T F[N];
};

我需要用{0,1,2,...,N-1} 构造F[] 的元素。如果可能的话,我想避免递归定义模板结构,将最后一级定义为template&lt;class T&gt; struct A&lt;T,0&gt; 并做一些复杂的模板技巧。 C++11 初始化列表有帮助吗?

这类似于Template array initialization with a list of values,但它不构造值递增的元素。它稍后在运行时循环中设置它。

【问题讨论】:

  • 这里为什么不能使用array
  • 可以,但不能解决这个问题

标签: c++ templates c++11


【解决方案1】:

您可以使用可变参数值模板和构造函数委托来做到这一点:

template<int... I> struct index {
    template<int n> using append = index<I..., n>; };
template<int N> struct make_index { typedef typename
    make_index<N - 1>::type::template append<N - 1> type; };
template<> struct make_index<0> { typedef index<> type; };
template<int N> using indexer = typename make_index<N>::type;

template<class T, int N>
struct A {
  template<T...I> A(index<I...>): F{I...} {}

  A(): A(indexer<N>{}) {}

  T F[N];
};

这使用来自Calling a function for each variadic template argument and an array的序列包生成器

【讨论】:

  • using 的使用对解决方案至关重要吗?
  • @Frank 不,它总是可以替换为typedef。在这种情况下很方便。
  • 我投了赞成票 - 我喜欢模板在新标准中完全不可读的方式;-)
  • @Pawel:稍微格式化一下会有很大帮助,甚至可能是another implementation of the indices trick
【解决方案2】:

假设某种indices 解决方案可用:

A(): A(make_indices<N>()) {}

// really a private constructor
template<int... Indices>
explicit A(indices<Indices...>)
    // Can be an arbitrary expression or computation, too, like
    // (Indices + 3)...
    : F {{ Indices... }}
{}

如果您的编译器不支持委托构造函数,一种选择是切换到 std::array&lt;T, N&gt; 并使用返回初始化数组的私有静态助手,这样默认构造函数将变为:

A(): F(helper(make_indices<N>())) {}

这当然会导致额外的(移动)构造。

【讨论】:

  • using 是否完全有必要。我的编译器 GCC 4.6 不理解它
  • @Frank 你也可以引入类型同义词typedef
  • 如果这样做,我会得到:错误:类型‘A’不是‘A’的直接基数
  • @Frank 4.6 不支持委托构造函数。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-07-02
  • 2017-02-28
  • 2013-07-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多