【问题标题】:Class with a deleted copy constructor can be still copied?删除了复制构造函数的类仍然可以复制吗?
【发布时间】:2021-07-20 09:34:32
【问题描述】:

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

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

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

【问题讨论】:

  • 你的编译器是什么?
  • 您可以将第二个参数作为std::move(atomic<int>{ }) 传递,这应该强制调用移动构造函数。
  • @KarenBaghdasaryan - 没有移动构造函数。用户声明的复制构造函数(甚至是已删除的构造函数)不允许隐式生成移动 c'tor。

标签: c++ c++17 atomic copy-constructor move-constructor


【解决方案1】:

foo({ });中,参数为copy list-initialized。结果它被std::atomic的默认构造函数初始化。

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

首先,如果 T 是类类型并且初始化程序是纯右值表达式,其 cv 非限定类型与 T 相同,则初始化程序表达式本身,而不是从它的临时物化,用于初始化目标对象: 见copy elision (C++17 起)

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

【讨论】:

    猜你喜欢
    • 2014-05-30
    • 1970-01-01
    • 2019-04-12
    • 2022-07-06
    • 1970-01-01
    • 2014-08-25
    • 2012-10-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多