复制构造函数隐式定义为已删除的情况

时间:2014-11-12 05:31:50

标签: c++ constructor

N3797::12.8/11 [class.copy]部分说:

  

隐式声明的复制/移动构造函数是内联公共   同类的成员。 X类的默认复制/移动构造函数   如果X有:

,则定义为已删除(8.4.3)      

[...]

     

- 非静态数据   类型M(或其数组)的成员,无法复制/移动   因为重载决议(13.3),适用于M的相应   构造函数,导致歧义或删除的函数或   默认构造函数无法访问

关于相应的复制/移动构造函数的歧义的第一个案例非常清楚。我们可以写下以下内容:

#include <iostream>
using namespace std;

struct A
{
    A(){ }
    A(volatile A&){ }
    A(const A&, int a = 6){ }
};

struct U
{
    U(){ };
    A a;
};

U u;

U t = u;

int main(){ }

反映这一点。但是或从默认构造函数中删除或无法访问的函数呢?使用默认构造函数无法访问的函数有什么问题?你能举一个反映这个的例子吗?

2 个答案:

答案 0 :(得分:6)

简单地说:

struct M { M(M const&) =delete; };
struct X { X(X const&) =default; M m; }; // X(X const&) is actually deleted!

隐式声明的函数也被视为“默认”([dcl.fct.def.default] / 5);更熟悉的前C ++ 11示例可能类似于:

struct M { protected: M(M const&); };
struct X { M m; }; // X's implicit copy constructor is deleted!

请注意,如果在声明之后明确默认函数,则如果隐式删除该函数,程序将会格式错误([dcl.fct.def.default] / 5) :

struct M { M(M const&) =delete; };
struct X { X(X const&); M m; };

X::X(X const&) =default; // Not allowed.

答案 1 :(得分:0)

  

类型M(或其数组)的非静态数据成员,由于重载解析(13.3),无法复制/移动,因为应用于M的相应构造函数,会导致歧义或函数从默认构造函数中删除或无法访问

措辞也许是略有做法,因为最简洁。正如上面所强调的那样,这个想法是有问题的函数 M 复制构造函数正在重载,导致它无法访问。因此,让M成员的副本构造函数为protected delete X的复制构造函数。M。同样,简单地删除{{1}}的复制构造函数也会产生相同的结果。