【问题标题】:Inheritance of copy constructors in C++17C++17中复制构造函数的继承
【发布时间】:2019-09-13 15:57:47
【问题描述】:

考虑以下示例:

struct Parent
{
    Parent ();

    Parent (const Parent &);
};

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

Parent p;

Child c (p);

这取自以下问题:Why "an inherited constructor is not a candidate for initialization from an expression of the same or derived type"?

最初的问题是关于 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 中格式不正确吗?如果是这样,为什么?

【问题讨论】:

标签: c++ inheritance language-lawyer c++17 copy-constructor


【解决方案1】:

[over.match.funcs]/8:

从类类型 C ([class.inhctor.init]) 继承的构造函数,其第一个参数类型为“引用 cv1 P”(包括从如果参数列表只有一个参数并且CP 和@ 引用相关,则在构造cv2 D 类型的对象时,从候选函数集中排除987654328@ 与 D 引用相关。

CWG2356

【讨论】:

  • 这算是回溯到 C++17 了吧?
  • 是的,它是 DR。
  • 您是否知道为什么解决方案不是简单地恢复已删除的段落以防止这样的构造函数被继承?这个解决方案是否允许这些构造函数在其他上下文中保持可见?
  • 在重载解析时间之前,您无法判断构造函数模板最终的外观。
猜你喜欢
  • 2019-01-12
  • 2014-06-15
  • 2012-09-20
  • 1970-01-01
  • 1970-01-01
  • 2014-08-21
  • 1970-01-01
  • 2017-08-09
  • 2015-04-11
相关资源
最近更新 更多