删除复制构造函数或复制赋值运算符是否计为"用户声明"?

acm*_*acm 6 c++ move copy-constructor language-lawyer c++11

根据此演示文稿,如果复制构造函数或复制赋值运算符是"用户声明的",则不会生成隐式移动操作.请问delete荷兰国际集团的拷贝构造函数或拷贝赋值运算符计数为"用户声明"?

struct NoCopy {
    NoCopy(NoCopy&) = delete;
    NoCopy& operator=(const NoCopy&) = delete;
};
Run Code Online (Sandbox Code Playgroud)

是否会为NoCopy类生成隐式移动操作?或者删除相关的复制操作是否计为"用户声明",从而禁止隐式移动生成?

如果可能的话,我更愿意参考标准的相关部分.

Law*_*vil 7

根据演示文稿的幻灯片14,删除的复制构造函数是"用户声明",从而禁止移动生成.


Cas*_*sey 7

术语"用户声明"在标准中没有正式定义.它与特殊成员函数的上下文中的"隐式声明"相反.[dcl.fct.def.default]/4对于这个事实可能会更清楚一点,但目的是:

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

这两个NoCopy(NoCopy&) = delete;NoCopy& operator=(const NoCopy&) = delete;是特殊的成员函数的声明.由于明确声明它们,而不是允许编译器隐式声明它们,因此它们是用户声明的.因此,这些声明将禁止移动构造函数的隐式声明,并按[class.copy]/9移动赋值运算符:

如果类的定义X没有显式声明一个移动构造函数,那么当且仅当一个类的定义被隐式声明为默认值时

- X没有用户声明的复制构造函数,

- X没有用户声明的复制赋值运算符,

- X没有用户声明的移动赋值运算符,

- X没有用户声明的析构函数,和

- 移动构造函数不会被隐式定义为已删除.