首页 > 解决方案 > C++17中复制构造函数的继承

问题描述

考虑以下示例:

struct Parent
{
    Parent ();

    Parent (const Parent &);
};

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

Parent p;

Child c (p);

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

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

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

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

using 声明声明一个类从基类继承构造函数时,基类的默认构造函数、复制构造函数和移动构造函数(如果有)被排除在引入的声明集中。

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

尽管如此,GCC 和 Clang 都拒绝它。铿锵声 说:

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

但是,我在标准中找不到任何这样的内容。

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

标签: c++inheritancelanguage-lawyerc++17copy-constructor

解决方案


[over.match.funcs]/8

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

参见CWG2356


推荐阅读