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

时间:2015-08-06 21:52:24

标签: c++ c++11

问题是我的头衔。

我问,因为我有一个带有默认移动构造函数的类,但尝试执行复制分配的代码失败,说明复制赋值运算符已删除(根据Visual Studio 2015)

所以我检查了隐式声明的复制赋值运算符的规则here

  

T类的隐式声明或默认的复制赋值运算符被定义为以下任何一种情况下删除:

     
      
  • ...
  •   
  • T具有用户声明的移动构造函数
  •   
  • T具有用户声明的移动赋值运算符
  •   

所以基本上我不确定默认的移动构造函数是否算作用户声明的。我的直觉告诉我是的,但是当谈到标准时,我总是喜欢确定,因为假设可能代价高昂。

2 个答案:

答案 0 :(得分:1)

标准说:

  

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

     

如果类定义没有显式声明复制构造函数,则会隐式声明一个。如果上课   definition声明一个move构造函数或move赋值运算符,隐式声明的复制构造函数   被定义为删除;否则,它被定义为默认值(8.4)。如果该类有,则不推荐使用后一种情况   用户声明的复制赋值运算符或用户声明的析构函数。

     

如果类定义没有显式声明一个复制赋值运算符,则会隐式声明一个。如果   类定义声明了一个移动构造函数或移动赋值运算符,即隐式声明的副本   赋值运算符定义为已删除;否则,它被定义为默认值(8.4)。如果类具有用户声明的复制构造函数或用户声明的析构函数,则不推荐使用后一种情况。

您的类默认移动构造函数,但它是显式声明的。 因此根据标准隐式声明的复制构造函数和复制赋值运算符被定义为已删除。

  

8.4.2明确违约的函数[dcl.fct.def.default]

     

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

使用此术语,您的移动构造函数是用户声明的,但不是用户提供的。

答案 1 :(得分:0)

默认的特殊成员函数是user- 声明的,但用户也定义作为默认值。该标准没有明确定义术语“用户声明”,但它实质上意味着必须由用户写出的任何特殊成员函数。所以下面声明了一个构造函数并将其定义为默认值。

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

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