没有数据成员和基类的类的隐式声明的复制构造函数

时间:2014-11-04 05:44:55

标签: c++ constructor

Standarad N3797::12.8/8 [class.copy]说:

  

类X的隐式声明的复制构造函数将具有   表格X :: X(const X&)if

     

- X的每个直接或虚拟基类B.   复制构造函数,其第一个参数是const B&的类型。或const   挥发性B&和

     

- 对于X的所有非静态数据成员   对于类型M(或其数组),每个这样的类类型具有副本   构造函数,其第一个参数是const M&的类型。或const   易变的M&。

     

否则隐式声明的复制构造函数将具有形式   X::X(X&)

我通过以下示例尝试了这个:

struct B
{
    B(){ }
    B(const B&){}
};

struct A : B
{
    A(){ };
};

const A a;

A t = a; //OK Lvalue reference to const A can be initialized with 
         //an lvalue of const A.

int main(){ }

DEMO

但是,如果我们从示例中删除class B,如下所示:

struct A
{
    A(){ };
};

const A a;

A t = a; //OK, Why?

int main(){ }

DEMO

它仍然可以正常工作。但由于copy-constructor应该具有A::A(A&)形式,我预计会发生编译时。实际上,如果我们编写以下代码:

struct A
{
    A(){ };
    A(A&){ };
};

const A a;

A t = a; //error: no matching constructor for initialization of 'A'

int main(){ }

DEMO

它会按照我的预期运作。

第二种情况是错误吗?

2 个答案:

答案 0 :(得分:0)

两种情况下隐式声明的复制构造函数都是A(const A &)形式,因为这是列表中的第一个案例,并且没有任何限制适用。

答案 1 :(得分:0)

如T.C.所述。 in the comments要求可能是空洞的 - 也就是说,根本没有基类,第一个项目符号的要求仍然满足:

  

- B的每个直接或虚拟基类X都有一个复制构造函数   其第一个参数是const B&const volatile B&类型,   和

如果没有直接或虚拟基类,则此条件的计算结果为true - 不需要至少一个具有适当拷贝构造函数的基类,它是要求没有不符合要求的基类,即具有不属于给定形式的复制构造函数。如果更清楚,您也可以重新编写文本:

  

- 如果X具有直接或虚拟基类,B的每个直接或虚拟基类X都有一个复制构造函数,其第一个参数类型为const B&const volatile B&,   和