Список инициализатора конструктора C ++ "ошибка: ожидается" ('или' {'' - PullRequest
1 голос
/ 15 апреля 2020

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

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>>()}{};
};

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

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

Спасибо!

1 Ответ

0 голосов
/ 15 апреля 2020

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

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

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

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

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

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

...