删除复制构造函数的类仍然可以复制吗?

Mic*_*hal 3 c++ atomic copy-constructor move-constructor c++17

我有一个简单的功能: void foo(atomic<int> a) { }

碰巧我可以foo()通过这种方式调用:foo({ }); 但我不能以这种方式 调用: foo(atomic<int>{ });由于错误消息copy constructor is a deleted function。我是用 C++14 编译的。

  1. 第一种方式调用什么构造函数:创建构造函数还是移动构造函数?
  2. 为什么在第二种方式中没有调用例如移动构造函数?
  3. 这两个调用foo()可以用 C++17 编译 - 为什么?

son*_*yao 6

在 中foo({ });,参数是复制列表初始化的。结果,它由 的默认构造函数初始化std::atomic

在 中foo(atomic<int>{ });,参数是从临时(即)复制初始化的。在 C++17 之前,即使复制/移动操作可能会被省略,复制/移动构造函数仍然必须存在且可访问。由于 C++17 由于强制复制省略而不再需要 this ,因此保证参数由直接的默认构造函数初始化。std::atomicatomic<int>{ }std::atomic

首先,如果 T 是一个类类型并且初始化器是一个纯右值表达式,其 cv-unqualified 类型与 T 是相同的类,则初始化器表达式本身,而不是从它具体化的临时对象,用于初始化目标对象:参见副本省略(C++17 起)

在以下情况下,编译器需要省略类对象的复制和移动构造,即使复制/移动构造函数和析构函数具有可观察到的副作用。对象被直接构建到存储中,否则它们将被复制/移动到那里。复制/移动构造函数不需要存在或可访问:(C++17 起)