五和隐式删除函数的规则

Eli*_*ion 5 c++ rule-of-three c++11

就我的理解,五法则是指导性法则。尽管如此,我已经看到编译器在某些情况下可能会隐式删除函数。例如,当定义一个 move-ctor' 时,复制分配/复制 ctor' 将被删除。

我想知道是否有提到的更多场景。换句话说,自定义函数在哪些场景下可以隐式删除其他函数?

谢谢

编辑:
参考一些涵盖该主题的来源也可以!

nyr*_*ium 4

对于所有“五”,该标准定义了在什么情况下它们将被隐式声明为删除。我已经为您命名并引用了 C++ 标准N4659中的相关部分:

\n\n
    \n
  • (12.3.3) 定义联合时,可以隐式删除五个联合中的一些:\n\n
    \n

    [..] [ 注意:如果联合体的任何非静态数据成员具有非平凡的默认构造函数 (15.1)、复制构造函数 (15.8)、移动构造函数 (15.8),则缺少默认成员初始值设定项 (12.2) )、复制赋值运算符 (15.8)、移动赋值运算符 (15.8)\n 或析构函数 (15.4),联合体的相应成员函数必须由用户提供,否则将被\n 隐式删除 (11.4.3)并集 \xe2\x80\x94 尾注]

    \n
  • \n
  • (15.1) 当没有用户定义的替代项时,将隐式声明“五”:\n\n
    \n

    默认构造函数 (15.1)、复制构造函数和复制赋值运算符 (15.8)、移动构造函数和移动赋值运算符 (15.8) 以及析构函数 (15.4) 是特殊成员函数。[\n 注意:\n 当程序未显式声明这些成员函数时,\n 实现将隐式声明某些类类型的这些成员函数。如果它们是 odr 使用的,则实现将隐式定义它们 (6.2)。参见 15.1、\n 15.4 和 15.8。\n \xe2\x80\x94 尾注\n ]

    \n
  • \n
  • (15.1.1) 隐式删除构造函数:\n\n
    \n

    如果满足以下条件,则类 X 的默认默认构造函数被定义为已删除:
    \n \xe2\x80\x94 (5.1) X 是一个联合体,其变体成员具有非平凡的默认构造函数,并且 X 的变体成员没有默认成员初始值设定项,
    \n \xe2\x80\x94 (5.2) X 是一个非联合类,它具有一个带有非平凡默认构造函数的变体成员 M,并且包含 M 的匿名联合的变体成员没有默认成员初始值设定项,
    \ n \xe2\x80\x94 (5.3) 任何没有默认成员初始值设定项 (12.2) 的非静态数据成员都是引用类型,
    \n \xe2\x80\x94 (5.4) 任何非变体非静态数据成员没有大括号或等号初始化程序的 const 限定类型(或其数组)没有用户提供的默认构造函数,
    \n \xe2\x80\x94 (5.5) X 是联合体,其所有变体成员都是const 限定类型(或其数组),
    \n \xe2\x80\x94 (5.6) X 是非联合类,并且任何匿名联合成员的所有成员都是 const 限定类型(或其数组),
    \ n \xe2\x80\x94 (5.7) 任何可能构造的子对象(带有大括号或等于初始化器的非静态数据成员除外)都具有类类型 M (或其数组),并且 M 没有默认构造函数或应用于查找 M \xe2\x80\x99s 相应构造函数的重载解析 (16.3) 会导致歧义或导致函数被删除或无法从默认默认构造函数访问,或
    \n \xe2\x80\x94 (5.8) 任何潜在构造的子对象具有带有析构函数的类型,该析构函数已被删除或无法从默认的默认构造函数访问

    \n
  • \n
  • (15.8.1.10) 隐式删除复制/移动构造函数:\n\n
    \n

    类 X 的默认复制/移动构造函数被定义为已删除 (11.4.3),如果 X 具有:
    \n \xe2\x80\x94 (10.1) 具有非平凡对应构造函数的变体成员,并且 X 是联合体 -像类一样,
    \n\xe2\x80\x94(10.2)一个潜在构造的子对象类型M(或其数组),由于重载解析(16.3)而无法复制/移动,应用于查找对应的M\xe2\x80\x99s构造函数,导致歧义或从默认构造函数中删除或无法访问的函数,
    \n \xe2\x80\x94 (10.3) 具有已从默认构造函数中删除或无法访问的析构函数的类型的任何潜在构造的子对象,或者,
    \n \xe2\x80\x94 (10.4) 表示复制构造函数,右值引用类型的非静态数据成员。重载决策会忽略定义为已删除的默认移动构造函数(16.3、16.4)。[ 注意:删除的移动构造函数会干扰右值的初始化,右值可以使用复制构造函数。\xe2\x80\x94 尾注]

    \n
  • \n
  • (15.8.2) 隐式删除复制/移动赋值运算符:\n\n
    \n

    如果 X 具有:
    \n \xe2\x80\x94 (7.1) 具有非平凡对应赋值运算符的变体成员,并且 X 是类联合类,则类 X 的默认复制/移动赋值运算符被定义为已删除,或者
    \n \xe2\x80\x94 (7.2) const 非类类型(或其数组)的非静态数据成员,或
    \n \xe2\x80\x94 (7.3) 引用类型的非静态数据成员,或
    \n \xe2\x80\x94 (7.4) 类类型 M (或其数组)的直接非静态数据成员或直接基类 M,由于重载解析 (16.3) 的应用而无法复制/移动查找 M \xe2\x80\x99s 对应的赋值运算符会导致歧义或函数被删除或无法从默认赋值运算符访问。

    \n
  • \n
  • (15.4.5) 隐式删除析构函数:\n\n
    \n

    类 X 的默认析构函数被定义为已删除,如果:
    \n \xe2\x80\x94 (5.1) X 是一个类似联合的类,具有带有非平凡析构函数的变体成员,
    \n \xe2\x80\ x94 (5.2) 任何潜在构造的子对象都具有类类型 M (或其数组),并且 M 具有已删除的析构函数或无法从默认析构函数访问的析构函数,
    \n \xe2\x80\x94 (5.3) 或对于虚拟析构函数,非数组释放函数的查找会导致歧义,或者导致函数被删除或无法从默认析构函数访问。

    \n
  • \n
\n