【问题标题】:Inheriting constructor and providing new overload: no arguments base constructor seems to not participate in overload resolution [duplicate]继承构造函数并提供新的重载:无参数基础构造函数似乎不参与重载决议[重复]
【发布时间】:2015-04-26 14:22:54
【问题描述】:

测试显示一个奇怪的行为(c++14g++ 4.9.1clang 3.5.5):

总结一下:

  • 如果B 没有提供其他可以使用的构造函数A::A()
  • 如果B 提供了其他构造函数,它不能使用A::A(),但它使用A::A(whatever arguments),这是出乎意料的行为(至少对我而言)。

设置 1:

struct A {
  A() {};
  A(int) {}; // with or without this overload the result are the same
};

struct B : A {
  using A::A;
};

B b0{}; // OK

设置 2:

struct A {
  A() {}; // with a default constructor instead (empty class A)
          // the results are the same
};

struct B : A {
  using A::A;
  B(int){}
};

B b0{}; // no matching constructor
B b1{24}; // OK

设置 3:

struct A {
  A() {};
  A(int) {};
};

struct B : A {
  using A::A;
  B(int, int){}
};

B b0{}; // no matching constructor
B b1{24}; // OK
B b2{24, 42}; // OK

为什么会发生这种情况以及如何“修复”它。

【问题讨论】:

  • 默认构造函数是特殊的。您可以“修复”它,例如通过编写显式声明默认构造函数并将其默认:B() = default; 我猜默认构造函数的某些属性不能被继承构造函数“复制”,例如琐碎,因此有特殊规则。
  • 这些是您正在构建的确切示例,它们不起作用还是我?你能提供一个实时链接吗?即wandboxColiru
  • @dyp 你是对的。为什么不将您的评论放入答案中? ;)
  • 示例不应该是真实的。一方面,你没有继承任何东西。请创建一个MCVE
  • sry,我输入而不是复制,修复了继承。

标签: c++ overloading c++14 inheriting-constructors


【解决方案1】:

我不能告诉你这样做的理由,但我至少可以告诉你这是标准规定的:

[C++11: 12.9/3]:对于候选继承构造函数集合中的每个非模板构造函数除了没有参数的构造函数或具有单个参数的复制/移动构造函数,构造函数被隐式声明除非在 using-declaration 出现的类中存在具有相同签名的用户声明的构造函数,否则具有相同的构造函数特征。 [..]

由于默认的B() 调用默认的A(),您可以这样“修复”它:

struct B : A
{
   B() = default;

   using A::A;
   B(int, int){}
};

(live demo)

以下wording from the original proposal (n2540) 表明此修复程序的易用性和对称性或多或少是决定背后的驱动因素,尽管我仍然觉得这有点不令人满意。哦,好吧。

不转发复制和默认构造函数,遵从现有的隐式声明复制/默认构造函数的规则。

【讨论】:

    猜你喜欢
    • 2017-11-20
    • 2021-09-14
    • 2012-07-22
    • 2015-08-22
    • 2012-11-30
    • 2016-12-05
    • 2014-08-21
    • 1970-01-01
    相关资源
    最近更新 更多