为什么即使有删除的复制构造函数,std::atomic也能在C++17中编译?

11

我有一个简单的代码:

#include <atomic>

int main()
{
    std::atomic<int> a = 0;
}

这段代码使用 -std=c++17 编译通过,但是使用 -std=c++14 和 -std=c++11 会编译失败。

使用已删除函数 std::atomic::atomic(const std::atomic&)

为什么会这样呢?在 C++17 中,类 std::atomic 仍然没有拷贝构造函数。那么为什么这段代码在 -std=c++17 下是合法的呢?

当然我知道更推荐使用 {} 的风格,但我只是好奇为什么上述代码从 C++17 开始可以编译通过。

1个回答

14
自 C++17 开始,复制省略是被保证的。对于 std::atomic<int> a = 0;,要求从 0 直接初始化 a

注意:上述规则并未指定一种优化方式。C++17 核心语言规范中的 prvalues 和临时对象与早期的 C++ 修订版本有根本不同的区别:不再存在需要复制/移动的临时对象。描述 C++17 机理的另一种方法是“未实现值传递”:prvalues 被返回和使用,而不必实现临时对象。

在 C++17 之前,即使复制/移动操作(从初始化为 0 的临时对象 std::atomic<int> 初始化 a)可能会被优化掉(在复制初始化中),但仍然需要访问复制/移动构造函数。

通常最后一步会被优化掉,转换结果直接在分配给目标对象的内存中构造,但即使未使用,也需要访问合适的构造函数(移动或复制)。(直到 C++17)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接