如果在C ++ 17中“删除”或“未声明”移动/复制构造函数/赋值,是否已建立?

时间:2019-05-12 15:03:32

标签: c++ language-lawyer c++17

我一直在关注this answerWhat are the rules for automatic generation of move operations?的相关问题,并希望答案现在已经确定。

基于类中已声明的内容,该幻灯片显示哪些构造函数/赋值运算符为“未声明”,“默认”或“已删除”:

enter image description here

那是从这些slides中摘录的,红色方框表示此行为已被弃用。

编译以下内容时:

#include <iostream>
struct X
{
  template<typename...T>
  X(T&&...) {
    std::cout << "Yay!\n";
  }

  ~X() {}
};

int main() {
  X x0;
  X x1{x0};
  X x2{std::move(x0)};
}

由于它们已编译且输出为“是!”,因此似乎未声明它们。三遍(至少对我来说这是件好事)。但是我想确认我可以依靠这种行为。

编辑

Frank指出,如果还添加了副本构造函数,它仍会显示“是!”。三遍,这是有趣的行为。做进一步的测试,如果添加了move构造函数,它只会说“是!”。两次。谁能解释这种行为?

1 个答案:

答案 0 :(得分:2)

根据N4659(几乎为C ++ 17标准),它们仍被定义为默认值,但行为(仍)已弃用。

  

如果类定义未显式声明一个副本构造函数,则将隐式声明一个非显式的构造函数。如果类定义声明了move构造函数或move赋值运算符,则隐式声明的copy构造函数将定义为delete;否则,被定义为默认值。如果该类具有用户声明的副本分配运算符或用户声明的析构函数,则后一种情况已弃用

  

如果类定义未显式声明一个拷贝赋值运算符,则隐式声明一个。如果类定义声明了move构造函数或move赋值运算符,则隐式声明的副本赋值运算符将定义为Delete;否则,被定义为默认值。如果该类具有用户声明的副本构造函数或用户声明的析构函数,则后一种情况已弃用