编译器能否生成引用不同 class 类型的默认复制构造函数?

Can the compiler generates a default copy constructor that takes reference to different class type?

我有这个例子

struct B { B(); };
struct D : B { };
D d{ B() }; // what happens here? or why it's well-formed

这是一个聚合初始化,但是看不懂d是怎么构造的?编译器是否隐式生成具有此签名 D::D(const D&)D::D(const B&) 或什么的复制构造函数?很明显,编译器不会生成 D::D(const D&),因为 const D& = B() 格式错误。所以这意味着它生成一个复制构造函数 D::D(const B&)?

现在如果我从 B 继承构造函数会发生什么:

struct B { B(); };
struct D : B { using B::B; };
D d{ B() }; // why it's ill-formed?

有人对我说 B 的默认复制构造函数 B::B(const B&) 被继承到 D 但它被排除在候选集合之外,这就是它格式错误的原因.是真的吗?

Can the compiler generates a default copy constructor that takes reference to different class type?

根据定义,没有。接受另一种类型对象的构造函数不是复制构造函数。它将是一个转换构造函数。

没有隐式生成这样的转换构造函数。

This is an aggregate initialization, but I can't understand how d is constructed?

在聚合初始化中没有调用封闭 class 的构造函数。子对象直接初始化。

D 是一个聚合,其基数 class 类型为 B。聚合初始化用于初始化此基础子对象。

It's clear that the compiler does not generate D::D(const D&) because const D& = B() is ill-formed.

前者不能从后者推导出来。事实上,有一个(微不足道的)D::D(const D&),您可以通过尝试复制初始化来证明它:

D d1{};
D d2(d1); // works

也就是说,普通构造函数是抽象机的概念,编译器实际上不必生成任何东西。


Now what would happen if I inherits constructors from B

struct D : B { using B::B; };
D d{ B() }; // why it's ill-formed?

具有继承的构造函数会使 class 失去聚合的资格,因此聚合初始化不适用。列表初始化将尝试调用构造函数,但不存在转换构造函数。