【问题标题】:Implicitly declared copy-constructor for classes without data-members and base-classes为没有数据成员和基类的类隐式声明复制构造函数
【发布时间】:2014-11-04 05:44:55
【问题描述】:

标准N3797::12.8/8 [class.copy] 说:

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

——X 的每个直接或虚拟基类 B 都有 第一个参数类型为 const B& 或 const 的复制构造函数 易变的 B& 和

——对于 X 的所有非静态数据成员 类类型 M(或其数组),每个这样的类类型都有一个副本 第一个参数类型为 const M& 或 const 的构造函数 不稳定的并购。

否则隐式声明的复制构造函数将具有以下形式 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

它仍然可以正常工作。但是由于复制构造函数应该具有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

它会像我预期的那样工作。

那么第二种情况是bug吗?

【问题讨论】:

    标签: c++ constructor


    【解决方案1】:

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

    【讨论】:

    • 为什么?标准规定否则,隐式声明的复制构造函数将具有 X::X(X&) 的形式。怎么了?
    • @DmitryFucintv:我们不在“否则”分支。我们在主分支。主分支之后的“if”评估为“true”。
    • 第二种情况下没有任何基类或非静态数据成员。为什么我们还在默认分支?你的意思是对于任何来自空集的元素保证吗?
    • 现在,我所有的保时捷都加油了,我所有的种植园都收获了,我所有的孩子都很开心。这是真的,尽管我没有钱,没有土地,也没有女人。我很确定你所有的宠物老虎都被喂饱了。 (这就是“所有人”的意思:不存在反例。)
    • 可以改写:隐式定义的 copy-ctors 参数是对类类型的 const 限定引用,如果所有子对象 copy-ctor(成员和基)都接受 @ 987654323@-合格的参考,否则不合格。
    【解决方案2】:

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

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

    如果没有直接或虚拟基类,则此条件评估为真 - 不需要至少一个具有适当复制构造函数的基类,但要求没有不满足要求的基类,即具有不属于给定形式的复制构造函数。如果这样更清楚,您也可以改写文本:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-11-28
      • 1970-01-01
      • 1970-01-01
      • 2019-11-28
      • 2014-11-26
      相关资源
      最近更新 更多