编译器是否提供默认的移动分配运算符和移动构造函数?

use*_*501 7 move-semantics c++11

编写类时,编译器(让我们使用g ++作为特定示例)是否提供默认的移动构造函数和默认的移动赋值运算符?

编译器提供默认值:

  • 构造函数(无参数),除非声明了另一个带有参数的构造函数。
  • 析构函数(大概什么都不做?-实际上不完全是,这个问题在这里有答案,它称为基类析构函数)
  • 复制构造函数,除非我们自己编写
  • 复制分配运算符,除非我们自己编写

编译器将提供默认的move构造函数还是move赋值运算符。

use*_*501 5

根据cppreference

隐式声明的移动构造函数

如果没有为类类型(结构、类或联合)提供用户定义的移动构造函数,并且以下所有条件都为真:

  • 没有用户声明的复制构造函数
  • 没有用户声明的复制赋值运算符
  • 没有用户声明的移动赋值运算符
  • 没有用户声明的析构函数(直到 C++14) 由于下一节中详述的条件,隐式声明的移动构造函数未定义为已删除

然后编译器将使用签名 T::T(T&&) 将移动构造函数声明为其类的非显式内联公共成员。

一个类可以有多个移动构造函数,例如 T::T(const T&&) 和 T::T(T&&)。如果存在一些用户定义的移动构造函数,用户仍然可以使用关键字 default 强制生成隐式声明的移动构造函数。

根据cppreference

隐式声明的移动赋值运算符

如果没有为类类型(结构、类或联合)提供用户定义的移动赋值运算符,并且以下所有条件都为真:

  • 没有用户声明的复制构造函数
  • 没有用户声明的移动构造函数
  • 没有用户声明的复制赋值运算符
  • 没有用户声明的析构函数(直到 C++14)隐式声明的移动赋值运算符不会被定义为已删除

然后编译器将使用签名 T& T::operator=(T&&) 将移动赋值运算符声明为其类的内联公共成员。

一个类可以有多个移动赋值运算符,例如 T& T::operator=(const T&&) 和 T& T::operator=(T&&)。如果存在一些用户定义的移动赋值运算符,用户仍然可以使用关键字 default 强制生成隐式声明的移动赋值运算符。

因为总是为任何类声明一些赋值运算符(移动或复制),所以基类赋值运算符总是隐藏的。如果 using 声明用于从基类中引入赋值运算符,并且其参数类型可能与派生类的隐式赋值运算符的参数类型相同,则 using 声明也被隐式隐藏宣言。