用户提供的构造函数与明确默认的构造函数

时间:2015-02-17 05:28:41

标签: c++ class constructor

N4296::12.8/11 [class.copy]告诉我们以下内容:

  

类X的默认复制/移动构造函数被定义为已删除   (8.4.3)如果X有:

     

[...]

     

(11.2) - 潜在构造的子对象类型M(或其数组)   由于重载决议(13.3),无法复制/移动   应用于M的相应构造函数,导致模糊或a   从默认删除或无法访问的功能   构造

     

[...]

所以不清楚为什么这个程序

struct X
{
};

struct Y
{
    X&& x; 
    Y(Y const&)= default;
};

int main() { }

DEMO

工作正常,但以下内容:

struct X
{
};

struct Y
{
    X&& x; 
    Y(Y const&);
};

Y::Y(Y const&)= default; //error

int main() { }

DEMO

1 个答案:

答案 0 :(得分:2)

[dcl.fct.def.default] / p5,强调我的:

  

如果用户声明的功能是用户提供的,则不是   在第一次声明中明确默认或删除。一个   用户提供的显式默认功能(即明确地)   在第一次声明后的默认值)定义在哪里   它被明确默认; 如果隐式定义了这样的函数   如删除,该程序格式不正确

这是有道理的,因为任何使用删除的函数都会导致程序格式错误,但是如果使用用户提供的显式默认函数,则可能无法在调用站点对此进行诊断:

// y.h
struct X
{
};

struct Y
{
    X&& x; 
    Y(Y const&);
};

// y.cpp
#include "y.h"
Y::Y(Y const&)= default; //defined as deleted

// main.cpp
#include "y.h"

int main() {
   Y y = Y();
}

编译main.cpp时,编译器不知道Y的复制构造函数,而不是它存在的;它不知道它是默认的,也不可能诊断它实际上是被删除的。可以诊断出这样一个错误的唯一地方就是明确默认功能。