为什么即使删除了复制构造函数,std::atomic 也会从 C++17 编译?

Why does std::atomic compile from C++17 even with a deleted copy constructor?

我有一个简单的代码:

#include <atomic>

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

此代码在 GCC 11.1.0 和 -std=c++17 下编译良好,但在 -std=c++14 和 -std=c++11 下编译失败。

using a deleted function std::atomic::atomic(const std::atomic&)

这是为什么?在 C++17 中 class std::atomic 仍然没有复制构造函数。为什么此代码对 -std=c++17 有效?

当然我知道首选的风格是使用 {},但我只是好奇为什么上面的代码自 C++17 以来编译得很好。

从 C++17 开始,这样的 copy elision 是有保证的。对于std::atomic<int> a = 0;a需要直接从0初始化。

Note: the rule above does not specify an optimization: C++17 core language specification of prvalues and temporaries is fundamentally different from that of the earlier C++ revisions: there is no longer a temporary to copy/move from. Another way to describe C++17 mechanics is "unmaterialized value passing": prvalues are returned and used without ever materializing a temporary.

在 C++17 之前,即使 copy/move 操作(从 0 初始化的临时 std::atomic<int> 初始化 a)可能被优化掉(在copy initialization),copy/move 构造函数仍然需要可访问。

The last step is usually optimized out and the result of the conversion is constructed directly in the memory allocated for the target object, but the appropriate constructor (move or copy) is required to be accessible even though it's not used. (until C++17)