Why can't member initializers use parentheses?

c++, member-initialization

Solution

One possible reason is that allowing parentheses would lead us back to the most vexing parse in no time. Consider the two types below:

struct foo {};
struct bar
{
  bar(foo const&) {}
};

Now, you have a data member of type `bar` that you want to initialize, so you define it as

struct A
{
  bar B(foo());
};

But what you've done above is declare a function named `B` that returns a `bar` object by value, and takes a single argument that's a function having the signature `foo()` (returns a `foo` and doesn't take any arguments).

Judging by the number and frequency of questions asked on StackOverflow that deal with this issue, this is something most C++ programmers find surprising and unintuitive. Adding the new brace-or-equal-initializer syntax was a chance to avoid this ambiguity and start with a clean slate, which is likely the reason the C++ committee chose to do so.

bar B{foo{}};
bar B = foo();

Both lines above declare an object named `B` of type `bar`, as expected.

Aside from the guesswork above, I'd like to point out that you're doing two vastly different things in your example above.

vector<int> v1{ 12, 1 };
vector<int> v2 = vector<int>(12, 1);

The first line initializes `v1` to a vector that contains two elements, `12` and `1`. The second creates a vector `v2` that contains `12` elements, each initialized to `1`.

Be careful of this rule - if a type defines a constructor that takes an `initializer_list<T>`, then that constructor is always considered first when the initializer for the type is a braced-init-list. The other constructors will be considered only if the one taking the `initializer_list` is not viable.

Problem

For example, I cannot write this: ``` class A { vector<int> v(12, 1); }; ``` I can only write this: ``` class A { vector<int> v1{ 12, 1 }; vector<int> v2 = vector<int>(12, 1); }; ``` Why is there a difference between these two declaration syntaxes?

Original source

Related problems