std::atomic<int> n = 6
中,由于 6
和 std::atomic<int>
不是同一类型(但是这里其实有一个用户定义转换序列,你可以简单的认为 6
可以隐式转换)。
即调用转换构造函数:
constexpr atomic( T desired ) noexcept;
6
会调用转换构造函数,构造出一个临时 atomic<int>
对象用来复制初始化 n
,即:
std::atomic<int> n = std::atomic<int>(6);
根据复制消除的规则:当初始化式是纯右值时,C++17 前通常会优化掉,C++17 起始终不会进行对移动构造函数的调用。
因此在 C++17 之前的版本,理所应当应该查找检测复制/移动 构造函数,满足要求才可以通过编译。但是实际上 atomic
的复制构造被删除(因为三/五/零法则,移动构造也被抑制生成)了,所以自然而然地不允许。
然而在 C++17 起,复制消除变为强制要求。纯右值表达式作为构造对象的参数,不会再调用移动构造,也不会去检测,而是原位构造。