【问题标题】:Initialization of std::array<T,N> in constructor initializer list when T is not default-constructible当 T 不可默认构造时,在构造函数初始化器列表中初始化 std::array<T,N>
【发布时间】:2018-06-11 12:07:57
【问题描述】:

this question 的启发,我想知道如果TN 都是模板参数并且T 不是默认可构造的,那么在构造函数初始化列表中构造std::array&lt;T,N&gt; 是否安全。我想出了以下辅助函数:

template <typename T, size_t... I> 
constexpr auto make_array_impl(std::index_sequence<I...>, const T& val) {
   return std::array<T, sizeof...(I)>{ (I, val)... };
}

template <typename T, size_t N>
constexpr auto make_array(const T& val) {
   return make_array_impl<T>(std::make_index_sequence<N>{}, val);  
}

现在,如果我有这样的课程:

class E {
   public:
      E() = delete;
      E(int, int, int) { }
};

我会写:

template <typename T, size_t N>
class A {
   public:
      template <typename... Args>
      A(Args&&... args) : a_(make_array<T, N>(T(std::forward<Args>(args)...))) { }

   private:
      std::array<T, N> a_;
};

然后

A<E, 5> a(1, 2, 3);

这适用于我启用 GCC 8.1 / Clang 6.0 和 C++14。但是,我不确定构造函数初始化列表中a_的这种初始化是否正确,如果正确,这种正确性是否取决于模板参数T

(说实话,我什至在标准中都找不到std::array是否可以被另一个std::array初始化。它是聚合初始化的一部分吗?或者,std::array是否支持复制初始化?)


为了澄清这个问题,我想通过什么来实现

A<E, 5> a(1, 2, 3);

a::a_ 成员函数是否会被有效地启动为

std::array<E, 5> a::a_ = { E(1,2,3), E(1,2,3), E(1,2,3), E(1,2,3), E(1,2,3) };

【问题讨论】:

  • N != 1 时,您不希望完美转发,否则您将多次从同一个源右值移动。
  • @ildjarn 感谢您指出这一点,我更新了代码。

标签: c++ arrays initializer-list


【解决方案1】:

除非你删除复制构造函数(或者隐式的被删除,这要求某些子对象具有已删除的复制构造函数或类似的东西),每个类型都可以进行复制构造。因此,对于任何(非数组对象)类型T 的值t,如果它是可复制构造的,T t2 = t; 将起作用。

【讨论】:

    猜你喜欢
    • 2015-12-29
    • 2016-10-18
    • 1970-01-01
    • 1970-01-01
    • 2018-10-04
    • 2015-09-04
    • 1970-01-01
    相关资源
    最近更新 更多