【发布时间】:2019-09-13 15:57:47
【问题描述】:
考虑以下示例:
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& 的构造函数:
对于候选继承构造函数集中的每个非模板构造函数,除了没有参数的构造函数或具有单个参数的复制/移动构造函数,构造函数被隐式声明为具有相同的构造函数特征,除非存在用户-用相同的声明构造函数 using-declaration 出现的类中的签名。
N4429 显着改变了继承构造函数的规范,并被认为可追溯至 C++11(我认为?)。 N4429 的目的是使基类构造函数像派生类构造函数一样可见,而不是声明派生类构造函数委托给基类构造函数。在 N4429 的第一个版本中,有以下措辞,保持 C++11 的限制:
当 using-declaration 声明一个类从基类继承构造函数时,基类的默认构造函数、复制构造函数和移动构造函数(如果有)被排除在引入声明。
然而,在本文的更新版本P0136R0 中,该措辞不再存在,并且没有解释原因。该文件再次修订,然后合并到标准中。所以在 C++17 中,我看不到任何会阻止上述代码编译的规则。
不过,GCC and Clang both reject it。 Clang 说:
继承的构造函数不是从相同或派生类型的表达式初始化的候选对象
但是,我在标准中找不到任何这样的说法。
这段代码在 C++17 中格式不正确吗?如果是这样,为什么?
【问题讨论】:
-
有趣的是我回答了this question 和 this question 并且仍然找不到规则...
标签: c++ inheritance language-lawyer c++17 copy-constructor