假设我有一个包含
std::atomic
成员数组的类,其中
数组的大小是通过计算确定的(即它可能会根据程序中其他地方的其他常量而改变):
class Foo {
static constexpr size_t kArraySize = ComputeArraySize();
std::atomic<size_t> atomics_[kArraySize];
};
确保原子全部初始化为最优雅的方法是什么 零?我可以比在
Foo
的构造函数中循环数组更好吗?
显式存储零? std::array
的答案是否不同?
通常我会在这里使用大括号初始值设定项,但派生长度( 可能很长)使它变得困难。
请注意,我不能假设
Foo
的实例具有静态存储
持续时间。
好吧,我相信我已经解决了这个问题。这两个都将初始化所有 原子归零:
std::atomic<size_t> plain_array[kArraySize] = {};
std::array<std::atomic<size_t>, kArraySize> std_array = {};
逻辑是这样的:
[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
确实有一个用户提供的构造函数,只是不是
用户提供的 default 构造函数(后者是明确默认的)。所以
从技术上讲,它不符合最后一点的条件。但看来这个
是标准中的错误,并且在最近的版本中已被修复
草稿。