被认为是用户声明的默认移动构造函数

Is a defaulted move constructor considered user-declared?

本文关键字:默认 移动 构造函数 声明 认为是 用户      更新时间:2023-10-16

问题是我的标题。

我问,因为我有一个类的默认移动构造函数,但代码试图执行复制赋值是失败的,说明复制赋值操作符是删除(根据Visual Studio 2015)。

我检查了这里隐式声明的复制赋值操作符的规则:

类T的隐式声明或默认复制赋值操作符定义为在下列任意条件下删除:

  • T有一个用户声明的move构造函数
  • T有一个用户声明的移动赋值操作符
所以基本上我不确定如果一个默认的移动构造函数计数为用户声明的。我的直觉告诉我是肯定的,但当涉及到标准时,我总是喜欢确定,因为假设可能代价高昂。

标准规定:

12.8复制和移动类对象[class.copy]

如果类定义没有显式声明复制构造函数,则隐式声明复制构造函数。如果这个类定义声明移动构造函数或移动赋值操作符,隐式声明复制构造函数被定义为已删除;否则,它被定义为默认值(8.4)。如果类有,则不建议使用后一种情况用户声明的复制赋值操作符或用户声明的析构函数。

如果类定义没有显式声明复制赋值操作符,则隐式声明。如果类定义声明移动构造函数或移动赋值操作符,即隐式声明的副本赋值操作符定义为deleted;否则,它被定义为默认值(8.4)。如果类具有用户声明的复制构造函数或用户声明的析构函数,则不建议使用后一种情况。

你的类有默认的move构造函数,但它是显式声明的。因此根据标准隐式声明复制构造函数和复制赋值操作符定义为删除。

8.4.2显式默认函数[dcl.fct.def.default]

显式默认函数和隐式声明函数统称为默认函数,实现应该为它们提供隐式定义(12.1 12.4,12.8),这可能意味着将它们定义为删除。如果函数是用户声明的,并且在第一次声明时没有显式默认或删除,则该函数是用户提供的。用户提供的显式默认函数(即,在其第一次声明之后显式默认)在显式默认的位置定义。

使用这个术语,move构造函数是用户声明的,而不是用户提供的。

一个默认的特殊成员函数是user-声明的,但它也是由用户默认定义的。该标准没有明确定义术语"用户声明",但它本质上是指必须由用户编写的任何特殊成员函数。因此,下面声明了一个构造函数,并将其定义为默认值。

struct X { 
    X() = default; // declaration and definition
};

将成员函数定义为默认值意味着定义等价于隐式定义。它是由用户声明的,因为它必须由用户输入。