假设我有一个带有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 确实有一个用户提供的构造函数,而不是用户提供的默认构造函数(后者显式默认).所以它在技术上并不符合最后一点的条件.但似乎这是标准中的一个错误,并已在最近的草案中得到修复.