c++ - 原子向量的初始化
问题描述
考虑:
void foo() {
std::vector<std::atomic<int>> foo(10);
...
}
foo 的内容现在有效吗?还是我需要显式循环并初始化它们?我已经检查过 Godbolt 并且看起来不错,但是在这一点上标准似乎很混乱。
std::vector构造函数说它插入默认插入的实例std::atomic<int>
,这些实例是通过放置初始化的值new
。
我认为值初始化的这种效果适用:
2) 如果 T 是一个类类型,其默认构造函数既不是用户提供也不是被删除(也就是说,它可能是一个具有隐式定义或默认的默认构造函数的类),则该对象被零初始化,然后它是如果它具有非平凡的默认构造函数,则默认初始化;
所以在我看来,原子是零初始化的。所以问题是,结果的零初始化是否会std::atomic<int>
产生有效的对象?
我猜答案是“在实践中是的,但它并没有真正定义”?
注意:这个答案同意它是零初始化的,但并没有真正说明这是否意味着该对象是有效的。
解决方案
你担心是对的。根据标准,原子具有调用的默认构造函数,但是它们还没有被初始化。这是因为默认构造函数没有初始化原子:
默认初始化
std::atomic<T>
不包含T
对象,其唯一有效用途是 std::atomic_init的破坏和初始化
这在某种程度上违反了正常的语言规则,并且某些实现无论如何都会初始化(正如您所指出的)。
话虽如此,我建议采取额外的步骤来确保 100% 确保它们根据标准正确初始化 - 毕竟您正在处理并发问题,其中错误可能极难追踪。
有很多方法可以避免这个问题,包括使用包装器:
struct int_atomic {
std::atomic<int> atomic_{0};//use 'initializing' constructor
};
推荐阅读
- html - 如何在asp.net mvc中的img src中传递变量
- sql - 如何从星期一到星期五对这个查询进行排序?
- java - 具有 recyclerview 和 tablayout 的动态高度查看器
- python - 如何在 Transformers 库中截断 Bert 标记器
- three.js - 如何将时间序列转换数据应用于三个 JS 对象
- arrays - 在函数中将数字插入指针数组
- regex - 我对正则表达式 `|` 的零长度匹配的解释是否正确?
- c++ - 如何将数组传递给函数以用作基于范围的for循环
- powerbi - TOTAL 正确,但缺少行
- r - 用两个data.table制作一个data.table,名称为column[2],不同