【问题标题】:C++11 Uniform initialization (i.e. list initialization) doesn't compile with inheritanceC++11 统一初始化(即列表初始化)不能通过继承编译
【发布时间】:2014-07-21 10:33:41
【问题描述】:
struct B { 
  int b; 
  B(int i = 0) : b(i) {};  // constructor
};

struct D : B  {
  int d;
};

int main () {
  D obj = {1};  // <-- error
  // D obj {1}; // <-- error (different)

}

以上代码无法编译,并给出:

error: could not convert ‘{1}’ from ‘<brace-enclosed initializer list>’ to ‘D’

即使我删除“构造函数”行也是如此。 如果我删除= 符号,即D obj {1};,那么它会给出以下信息:

error: no matching function for call to ‘D::D(<brace-enclosed initializer list>)’

解决此类问题的正确语法是什么?

【问题讨论】:

  • 您是否希望它默认构造B 并使用1 初始化d?或者用1 初始化B 并让d 未初始化?无论哪种方式,您都需要一个构造函数来解决歧义(或默认构造它,然后将成员设置为您想要的)。大括号初始化仅适用于具有匹配构造函数的聚合或类。
  • @MikeSeymour,即使我们删除 struct B 中的“constructor”行,错误仍然存​​在。
  • 当然可以。正如我所说,“大括号初始化仅适用于具有匹配构造函数的聚合或类”。您需要给D 一个合适的构造函数,或者默认构造它并在构造后设置它的成员。

标签: c++ inheritance c++11 compiler-errors list-initialization


【解决方案1】:

D 没有采用int 的构造函数。如果你想让它继承B的构造函数,就这么说吧,像这样:

struct D : B  {
  using B::B;
  int d;
};

不过,鉴于 D 有另一个 int 成员,您可能想做的还不止这些。

一个更完整的D 初始化B::b(通过调用B::B)和D::d 可能看起来像这样:

struct D : B  {
  D(int d_) : B(d_), d(d_) {}
  int d;
};

无论哪种方式,您的代码都需要说明 D 有一个构造函数采用 int

使用您的代码和我的 sn-p 链接到工作示例:http://goo.gl/YbSSHn

【讨论】:

  • 即使删除struct B中的“constructor”行,错误仍然存​​在。
  • 我不确定你的意思,@iammilind。我链接到一个编译良好的工作示例。你能证明你认为仍然有问题的地方吗?
  • 哎呀,好消息,@Jarod42。我想我已经看到了太多的 D 和 B,我的大脑一片空白。
【解决方案2】:

在您所写的D 中只有一个默认构造函数并且不知道如何调用B::B(int i)。您所要做的就是在D 中提供相应的构造函数,例如:

struct D : B  {
  D(int i) : B(i) {}//;
  int d;
};

【讨论】:

  • 你传播了iammilind的多余分号!我本来不想说什么,但现在是你们两个。
  • 谢谢。我会把分号注释掉:)
  • 我不会想到这个解决方案!
  • 对我也不行。我只是不想删除已评论的内容。
  • 我想你误解了我的意思。我的评论意味着“我自己永远不会想到那个解决方案”。 (但我喜欢它。)
猜你喜欢
  • 2016-09-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-07-27
  • 2012-05-17
  • 2019-07-10
相关资源
最近更新 更多