C++ constructor initializer list " error: expected '(' or '{'"

825 Views Asked by At

This doesn't compile:

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 '}'
};

But this does:

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

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

Please enlighten me, why I can't express as in the former? I looked for over an hour and couldn't find the explanation. I'm sure I've overlooked something simple.

clang version 9.0.0 (tags/RELEASE_900/final) Target: x86_64-apple-darwin17.7.0 clang++ -std=c++17

Thank you!

1

There are 1 best solutions below

0
Asteroids With Wings On

Because you just can't.

A constructor's member-initialiser is for initialising, well, members. Not selected members of members. It's a simple as that. There is just no feature to do what you want.

Could the C++ standard provide such a thing? Possibly. But in general it would open up all sorts of nasty edge cases with half-initialised objects, unclear semantics, and exception safety nightmares. (What would happen to the rest of the root object, if more existed? How would the object itself be initialised? In part? In full? When?)

All for absolutely no gain whatsoever.

Transitively invoking constructors keeps initialisation simple, clear, and always "owned" by the appropriate object in the code.

Use the member's own initialisation features, exactly as you are in your second example.