Ошибка списка инициализаторов конструктора С++: ожидается '(' или '{'

Это не компилируется:

class foo
{
  struct node
  {
    wchar_t val;
    unordered_map<wchar_t,unique_ptr<node>> children;
  };

  node root;

public:

  foo() : 
    root.val(L'า'), // error: expected '(' or '}'
    root.children(unordered_map<wchar_t, unique_ptr<node>>())
    {}; // error: expected '(' or '}'
};

Но это делает:

class foo
{
...<same as above> ....

    foo() : root{L'า', unordered_map<wchar_t, unique_ptr<node>>()}{};
};

Пожалуйста, просветите меня, почему я не могу выразить, как в прежнем? Я искал больше часа и не мог найти объяснение. Я уверен, что упустил что-то простое.

clang версия 9.0.0 (теги/RELEASE_900/final) Цель: x86_64-apple-darwin17.7.0 clang++ -std=c++17

Благодарю вас!


person Community    schedule 15.04.2020    source источник


Ответы (1)


Потому что ты просто не можешь.

Элемент-инициализатор конструктора предназначен для инициализации членов. Не выбранные члены членов. Это так просто. Там просто нет возможности делать то, что вы хотите.

Может ли стандарт C++ предоставить такую ​​вещь? Возможно. Но в целом это открыло бы всевозможные неприятные пограничные случаи с наполовину инициализированными объектами, неясной семантикой и кошмарами безопасности исключений. (Что случилось бы с остальной частью объекта root, если бы их было больше? Как бы инициализировался сам объект? Частично? Полностью? Когда?)

Все абсолютно без всякой выгоды.

Транзитивно вызываемые конструкторы делают инициализацию простой, понятной и всегда «принадлежат» соответствующему объекту в коде.

Используйте собственные функции инициализации члена, точно так же, как во втором примере.

person Asteroids With Wings    schedule 15.04.2020