如何优雅地对 std::atomic 数组进行零初始化?

问题描述 投票:0回答:1

假设我有一个包含

std::atomic
成员数组的类,其中 数组的大小是通过计算确定的(即它可能会根据程序中其他地方的其他常量而改变):

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

确保原子全部初始化为最优雅的方法是什么 零?我可以比在

Foo
的构造函数中循环数组更好吗? 显式存储零?
std::array
的答案是否不同?

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

请注意,我不能假设

Foo
的实例具有静态存储 持续时间。

c++ c++11 atomic stdatomic
1个回答
13
投票

好吧,我相信我已经解决了这个问题。这两个都将初始化所有 原子归零:

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 构造函数(后者是明确默认的)。所以 从技术上讲,它不符合最后一点的条件。但看来这个 是标准中的错误,并且在最近的版本中已被修复 草稿。

© www.soinside.com 2019 - 2024. All rights reserved.