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

时间:2015-03-10 12:20:10

标签: c++ c++11 move language-lawyer copy-constructor

Per this presentation,如果复制构造函数或复制赋值运算符是"用户声明",则不会生成隐式移动操作。将delete复制构造函数或复制赋值运算符计为"用户声明"?

struct NoCopy {
    NoCopy(NoCopy&) = delete;
    NoCopy& operator=(const NoCopy&) = delete;
};

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

如果可能的话,我更喜欢参考标准相关部分的答案。

2 个答案:

答案 0 :(得分:7)

根据演示文稿的幻灯片14,删除的复制构造函数是“用户声明”,因此禁止移动生成。

答案 1 :(得分: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没有用户声明的析构函数,

     

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