Почему я не могу использовать инициализацию списка для структуры с наследованием?

У меня есть куча простых структур, унаследованных от какого-то интерфейса, и я не могу использовать для них инициализацию списка:

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&&'


person Sairus    schedule 25.09.2020    source источник
comment
пожалуйста, включите сообщение об ошибке в вопрос   -  person 463035818_is_not_a_number    schedule 25.09.2020
comment
@Quimby Это не POD из-за виртуального метода.   -  person Barmar    schedule 25.09.2020
comment
@Barmar Я знаю, но ошибка возникает из-за наследования, она не связана с виртуальными методами.   -  person Quimby    schedule 25.09.2020


Ответы (1)


Структура Bar не является агрегатом, поскольку выполняет виртуальную функцию.

Из стандарта C++ 17 (агрегаты 11.6.1)

1 Агрегат представляет собой массив или класс (раздел 12) с

...

(1.3) — нет виртуальных функций (13.3) и

Таким образом, вы не можете инициализировать объект структурного типа как агрегат.

С другой стороны, в структуре нет конструктора с параметром.

Поэтому компилятор выдает ошибку для этого объявления

Bar b{ 11 };
person Vlad from Moscow    schedule 25.09.2020
comment
Итак, должен ли я писать тривиальные конструкторы для каждой из моих структур? :( - person Sairus; 25.09.2020
comment
@Sairus Вы должны написать конструктор с параметром для структуры Bar. - person Vlad from Moscow; 25.09.2020