首页 > 解决方案 > 原子向量的初始化

问题描述

考虑:

void foo() {
  std::vector<std::atomic<int>> foo(10);
  ...
}

foo 的内容现在有效吗?还是我需要显式循环并初始化它们?我已经检查过 Godbolt 并且看起来不错,但是在这一点上标准似乎很混乱。

std::vector构造函数说它插入默认插入的实例std::atomic<int>,这些实例是通过放置初始化的值new

我认为值初始化的这种效果适用:

2) 如果 T 是一个类类型,其默认构造函数既不是用户提供也不是被删除(也就是说,它可能是一个具有隐式定义或默认的默认构造函数的类),则该对象被零初始化,然后它是如果它具有非平凡的默认构造函数,则默认初始化;

所以在我看来,原子是零初始化的。所以问题是,结果的零初始化是否会std::atomic<int>产生有效的对象?

我猜答案是“在实践中是的,但它并没有真正定义”?

注意:这个答案同意它是零初始化的,但并没有真正说明这是否意味着该对象是有效的。

标签: c++vectoratomic

解决方案


你担心是对的。根据标准,原子具有调用的默认构造函数,但是它们还没有被初始化。这是因为默认构造函数没有初始化原子:

默认初始化std::atomic<T>不包含T对象,其唯一有效用途是 std::atomic_init的破坏和初始化

这在某种程度上违反了正常的语言规则,并且某些实现无论如何都会初始化(正如您所指出的)。

话虽如此,我建议采取额外的步骤来确保 100% 确保它们根据标准正确初始化 - 毕竟您正在处理并发问题,其中错误可能极难追踪。

有很多方法可以避免这个问题,包括使用包装器:

struct int_atomic {
   std::atomic<int> atomic_{0};//use 'initializing' constructor
};

推荐阅读