为什么对象的初始化调用复制构造函数

Why does the initialisation of an object invoke the copy constructor?

本文关键字:复制 构造函数 调用 初始化 对象 为什么      更新时间:2023-10-16

考虑以下最小工作示例:

#include <atomic>
int main() {
  ::std::atomic<bool> a = false;
}

副本和复制原子的分配均已明确删除。但是,这应该调用ctor完全bool。

g 和clang 抱怨说,这条线正在尝试调用 atomic的副本CTOR:

$ 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;
                      ^   ~~~~~

他们为什么要复制atomic

它试图调用复制构造函数,因为其移动构造函数已被隐式删除。

假设我们有一个X。

struct X
{
    X(const X&) = delete; // user-declared
    X(int)
    {
    }
};

现在,如果您要写

X x = 4;

它与

相同
X x = X(4); // copy/move into x, see 15.6.1

,您会遇到汇编错误,因为您明确删除了复制构造函数,因此没有被隐式声明的移动构造函数。

15.8.1复制/移动构造函数

[...]

如果类X类的定义没有明确声明移动构造函数,则在

时,将隐式地将一个不明显的人声明为违约
  • x没有用户指定的复制构造函数,
  • X没有用户宣布的复制分配运算符,
  • x没有用户宣布的移动分配运算符,
  • x没有用户宣布的驱动器。

[注意:当移动构造函数未隐含声明或 明确提供的表达方式,否则会调用 移动构造函数可以调用复制构造函数。 - end Note ]

在C 17中,这随着保证的副本的引入而改变。
这导致该线等于

X x(4);

不依赖副本或移动构造函数,而是调用X(int)

喜欢 x std :: atomic 也已明确删除其复制构造函数这就是为什么您的代码无法与C 17支持编译的原因。