【问题标题】:Value-initializing std::array member?值初始化 std::array 成员?
【发布时间】:2020-03-16 03:52:56
【问题描述】:

假设我有一个包含std::array 成员的类模板:

template<typename T>
class C {
public:
    C();

private:
    std::array<T, 42> a;
};

如何定义C::C 以使a 始终是值初始化的(不是默认初始化的)?即构造函数调用T() 来初始化a 的每个元素——例如,如果Tint,那么a 的每个元素都保证为零而不是不确定值?

int main() {
   C<int> c;
   assert(c.a[13] == 0); // ignoring private for exposition
}

更新

后人的附加信息:

  1. std::array 是具有单个元素 T[N] 的聚合类型
  2. 通过 init-list 初始化 std::array 是聚合初始化
  3. 使用空初始化列表进行聚合初始化会导致每个元素都没有被显式初始化。此类元素的初始化就像从空的 init-list 中复制初始化一样。
  4. 因此,数组T[N] 是从一个空的初始化列表复制初始化的。它也是一个聚合,因此 2 和 3 递归应用。
  5. T[N] 的 N 个元素中的每一个都是从空的 init-list 复制初始化的。
  6. 根据[dcl.init.list]/3,每个 T 对象都使用空的初始化列表进行复制列表初始化。到达该链的最后一个子句,内容如下:

否则,如果初始化列表没有元素,则对象被值初始化。

瞧。使用空的初始化列表 {} 初始化 std::array 会导致其元素被值初始化。

【问题讨论】:

    标签: c++ c++20


    【解决方案1】:

    你可以使用内联成员初始化:

    private:
        std::array<T, 42> a{};
    

    如果你绝对想用构造函数来代替(为什么?)那么:

    C()
        : a{}
    { }
    

    【讨论】:

    • C::C 的定义中看起来如何? (即问题要求定义C::C
    • @AndrewTomazos 你是什么意思?构造函数定义中不需要任何特殊内容。
    • 该问题要求定义C::C - 即答案应以C::C() /*...*/ 开头,而不是使用默认成员初始化程序。
    • ie C::C() : a{} {} 做同样的事情吗?它也可以吗?
    • @AndrewTomazos 这也可以解决,比如C() : a{func_returning_array()} {}
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-05
    • 2012-02-10
    • 1970-01-01
    • 2020-10-20
    • 2017-12-18
    • 2021-03-19
    相关资源
    最近更新 更多