为什么"an inherited constructor is not a candidate for initialization from an expression of the same or

Why "an inherited constructor is not a candidate for initialization from an expression of the same or derived type"?

本文关键字:an expression from of initialization the or same for candidate inherited      更新时间:2023-10-16

我希望这能工作

struct Parent
{
Parent ();
Parent (const Parent &);
};
struct Child : public Parent
{
using Parent::Parent;
};
Parent p;
Child c (p);

Child继承了Parent的所有构造函数,对吧?

包括Parent::Parent(const Parent &)

x.cpp:15:11: error: no matching function for call to ‘Child::Child(Parent&)’
Child c (p);
^
x.cpp:5:2: note: candidate: Parent::Parent(const Parent&)
Parent (const Parent &);
^~~~~~
x.cpp:10:16: note:   inherited here
using Parent::Parent;
^~~~~~
x.cpp:10:16: note:   an inherited constructor is not a candidate for initialization from an expression of the same or derived type
x.cpp:8:8: note: candidate: Child::Child()
struct Child : public Parent
^~~~~

为什么我不能从Parent构造Child

继承构造函数不会阻止编译器生成Child的默认复制构造函数。

这意味着您有一个隐藏无法通过查找解析选择的继承构造函数的Child::Child(const Child&),如 cppreference.com 解释的那样:

如果继承的构造函数与派生函数之一的签名匹配,则在Derived中找到的版本将隐藏该构造函数。如果Base的继承构造函数之一恰好具有与Derived的复制/移动构造函数匹配的签名,则不会阻止Derived复制/移动构造函数的隐式生成(然后隐藏继承的版本,类似于使用operator=(。

在 C++11 ISO 标准的 §12.9 中规定:

对于继承构造函数(构造函数除外(候选集合中的每个非模板构造函数 没有参数或具有单个参数的复制/移动构造函数,构造函数是隐式的 声明具有相同的构造函数特征,除非存在具有相同特征的用户声明构造函数 出现 using 声明的类中的签名。

这实质上是 CWG 问题 2356:不应继承基类复制和移动构造函数。

[over.match.funcs]/p9 现在说:

从类类型 C ([class.inhctor.init]( 继承的构造函数,如果第一个参数类型为"对 cv1 P 的引用"(包括从模板实例化的此类构造函数(,则在构造 cv2 D 类型的对象时,如果参数列表只有一个参数,并且 C 与 P 引用相关,P 与 D 引用相关,则从候选函数集中排除。

相关文章: