如何优雅地初始化std :: atomic数组?

jac*_*bsa 12 c++ c++11

假设我有一个带有std::atomics 成员数组的类,其中数组通过计算来调整大小(即它可能会根据程序中其他地方的其他常量而改变):

class Foo {
  static constexpr size_t kArraySize = ComputeArraySize();
  std::atomic<size_t> atomics_[kArraySize];
};
Run Code Online (Sandbox Code Playgroud)

确保原子全部初始化为零的最优雅方法是什么?我可以做的比在Foo构造函数中循环数组并显式存储零更好吗?答案std::array有何不同?

通常我会在这里使用大括号初始值设定项,但派生的长度(可能很长)会让它变得困难.

请注意,我不能假设该实例Foo具有静态存储持续时间.

jac*_*bsa 11

好的,我相信我已经完成了这项工作.这两个都将所有原子初始化为零:

std::atomic<size_t> plain_array[kArraySize] = {};
std::array<std::atomic<size_t>, kArraySize> std_array = {};
Run Code Online (Sandbox Code Playgroud)

这是逻辑:

  • [dcl.init.aggr]/1将数组定义为聚合.

  • [array.cons]/1强制要求std::array也是聚合.

  • [dcl.init.aggr]/7表示如果初始化列表中的元素少于聚合中的成员,则其余成员应从空初始化列表初始化.在这种情况下,这是所有成员.

  • [dcl.init.list]/3为具有默认构造函数的类的空列表定义列表初始化(如同std::atomic)以导致值初始化.

  • [dcl.init]/7表示没有用户提供的构造函数的类是零初始化的.假设std::array<T>包含一个数组T,并且零表示std::atomic<size_t>是我们所期望的,那么我们就是好的.

现在,std::atomic 确实有一个用户提供的构造函数,而不是用户提供的默认构造函数(后者显式默认).所以它在技术上并不符合最后一点的条件.但似乎这是标准中的一个错误,并已在最近的草案中得到修复.

  • 我相信底层原子对象由于 http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0883r0.pdf 中描述的令人惊讶的行为而处于未初始化状态。默认初始化不会执行您在此处期望的操作。 (2认同)
  • @Joe 似乎已修复 http://www.wg21.link/p0883 (2认同)