C ++ 17中副本构造函数的继承

Bri*_*ian 12 c++ inheritance copy-constructor language-lawyer c++17

考虑以下示例:

struct Parent
{
    Parent ();

    Parent (const Parent &);
};

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

Parent p;

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

这是从以下问题中得出的:为什么“继承的构造函数不是从相同或派生类型的表达式初始化的候选对象”?

最初的问题是关于C ++ 11的。在C ++ 11中,有一些措辞阻止Child获取采用以下内容的构造函数const Parent&

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

N4429极大地改变了继承构造函数的规范,并被认为可追溯到C ++ 11(我认为?)。N4429的目的是使基类构造函数看起来像是派生类构造函数一样可见,而不是声明委派给基类构造函数的派生类构造函数。在N4429的第一个版本中,有以下措词,保留了C ++ 11的限制:

using声明声明类从基类继承构造函数时,基类的默认构造函数,复制构造函数和move构造函数(如果有)将从引入的声明集中排除。

但是,在本文的更新版本P0136R0中,该措辞不再存在,并且没有给出原因的解释。该文件再次进行了修订,然后被合并为标准。因此,在C ++ 17中,我看不到任何阻止上述代码编译的规则。

尽管如此,GCC和Clang都拒绝了它。lang声:

继承的构造方法不是从相同或派生类型的表达式初始化的候选对象

但是,我无法在标准中找到类似这样的内容。

这段代码在C ++ 17中格式错误吗?如果是这样,为什么?

T.C*_*.C. 8

[over.match.funcs] / 8

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

参见CWG2356

  • 在重载解析时间之前,您无法确定构造器模板的外观。 (3认同)
  • 是的,这是DR。 (2认同)