为什么“继承的构造函数不是从相同或派生类型的表达式初始化的候选者”?

spr*_*aff 11 c++ inheritance constructor c++11

我希望这能奏效

struct Parent
{
    Parent ();

    Parent (const Parent &);
};

struct Child : public Parent
{
    using Parent::Parent;
};

Parent p;

Child c (p);
Run Code Online (Sandbox Code Playgroud)

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
        ^~~~~
Run Code Online (Sandbox Code Playgroud)

为什么我不能Child从 a构造a Parent

Jac*_*ack 5

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

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

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

在 C++11 ISO 标准的 §12.9 中是这样说的:

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

  • @Mansoor 通过 `using Parent::Parent` 指令告诉编译器确实从父类继承构造函数。 (2认同)

cme*_*erw 5

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

\n

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

\n
\n

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

\n
\n