bit*_*ask 8 c++ initialization atomic copy-constructor
考虑以下最小的工作示例:
#include <atomic>
int main() {
::std::atomic<bool> a = false;
}
Run Code Online (Sandbox Code Playgroud)
复制ctor和原子的复制分配都被明确删除.但是,这应该调用ctor完全是一个bool.
g ++和clang ++都抱怨此行试图调用以下内容的副本atomic:
$ g++ -std=c++1z a.cpp
a.cpp: In function ‘int main()’:
a.cpp:4:27: error: use of deleted function ‘std::atomic<bool>::atomic(const std::atomic<bool>&)’
::std::atomic<bool> a = false;
^~~~~
$ clang++ -std=c++1z a.cpp
a.cpp:4:23: error: copying variable of type '::std::atomic<bool>' invokes deleted constructor
::std::atomic<bool> a = false;
^ ~~~~~
Run Code Online (Sandbox Code Playgroud)
他们为什么要复制atomic?
它尝试调用复制构造函数,因为它的移动构造函数已被隐式删除。
\n\n假设我们有一个 X 类。
\n\nstruct X\n{\n X(const X&) = delete; // user-declared\n\n X(int)\n {\n }\n};\nRun Code Online (Sandbox Code Playgroud)\n\n现在,如果你要写
\n\nX x = 4;\nRun Code Online (Sandbox Code Playgroud)\n\n它会是一样的
\n\nX x = X(4); // copy/move into x, see 15.6.1\nRun Code Online (Sandbox Code Playgroud)\n\n并且您会收到编译错误,因为您显式删除了复制构造函数,因此没有隐式声明移动构造函数。
\n\n\n\n\n15.8.1 复制/移动构造函数
\n\n[...]
\n\n如果类 X 的定义没有显式声明移动构造函数,则非显式移动构造函数将被隐式声明为默认当且仅当
\n\n\n
\n\n- X 没有用户声明的复制构造函数,
\n- X 没有用户声明的复制赋值运算符,
\n- X 没有用户声明的移动赋值运算符,并且
\n- X 没有用户声明的析构函数。
\n[注意:当未隐式声明或显式提供移动构造函数时,本来会调用移动构造函数的表达式可能会调用复制构造函数。\xe2\x80\x94尾注]
\n
在 C++17 中,这种情况随着保证复制省略的引入而改变。
\n这导致该行等于
X x(4);\nRun Code Online (Sandbox Code Playgroud)\n\n它不依赖于复制或移动构造函数,而是调用X(int).
与X一样,std::atomic也显式删除了其复制构造函数\n这就是为什么如果未使用 C++17 支持进行编译,您的代码将无法编译。
\n