Per this presentation,如果复制构造函数或复制赋值运算符是"用户声明",则不会生成隐式移动操作。将delete
复制构造函数或复制赋值运算符计为"用户声明"?
struct NoCopy {
NoCopy(NoCopy&) = delete;
NoCopy& operator=(const NoCopy&) = delete;
};
是否会为NoCopy
类生成隐式移动操作?或删除相关的复制操作计为"用户声明"从而抑制隐式移动生成?
如果可能的话,我更喜欢参考标准相关部分的答案。
答案 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
没有用户声明的析构函数,- 移动构造函数不会被隐式定义为已删除。