首页 > 解决方案 > 为什么我不能将列表初始化用于具有继承的结构?

问题描述

我有一堆从某个接口继承的简单结构,我不能为它们使用列表初始化:

https://godbolt.org/z/PWjPzK

#include <iostream>
#include <string>

class Foo
{
public:
  virtual void write() = 0;
};

struct Bar : public Foo // if I remove this inheritance, it will compile
{
  int num;
  void write()
  {
    std::cout << "num = " << num;
  }
};

int main()
{
    Bar b{ 11 }; // error here
    b.write();
    return 0;
}

编辑:编译器输出有几个警告和错误:

<source>:21:15: error: no matching function for call to 'Bar::Bar(<brace-enclosed initializer list>)'
   21 |     Bar b{ 11 };
      |               ^
<source>:10:8: note: candidate: 'Bar::Bar()'
   10 | struct Bar : public Foo // if I remove this inheritance, it will compile
      |        ^~~
<source>:10:8: note:   candidate expects 0 arguments, 1 provided
<source>:10:8: note: candidate: 'constexpr Bar::Bar(const Bar&)'
<source>:10:8: note:   no known conversion for argument 1 from 'int' to 'const Bar&'
<source>:10:8: note: candidate: 'constexpr Bar::Bar(Bar&&)'
<source>:10:8: note:   no known conversion for argument 1 from 'int' to 'Bar&&'

标签: c++classinheritanceconstructorlist-initialization

解决方案


结构 Bar 不是聚合,因为它具有虚函数。

来自 C++ 17 标准(11.6.1 聚合)

1 聚合是一个数组或一个类(第 12 条)

...

(1.3) — 没有虚函数(13.3),并且

因此,您可能不会将结构类型的对象初始化为聚合。

另一方面,该结构没有带参数的构造函数。

所以编译器为此声明发出错误

Bar b{ 11 };

推荐阅读