I get the idea behind uniform initialization with curly braces. But why is that using this syntax on types that have a constructor that takes an initializer list, calls that specific constructor, even though the arguments are only wrapped in a single pair of curly braces, i.e.
int main(int argc, const char ** argv)
{
vector<int> vs0{3};
for(int v : vs0)
{
cout << v << ' ';
}
cout << '\n';
vector<int> vs1(3);
for(int v : vs1)
{
cout << v << ' ';
}
}
/*
Output
3
0 0 0
*/
Why does vs0 get constructed with the initializer list constructor? Shouldn't it be
vector<int> v2{{3}};
for that? It's kind of confusing, especially if you're not aware that a class has a constructor that takes an initializer list.
If the class has a constructor taking std::initializer_list, then it'll be preferred when being passed a braced-init-list in list initliazation.
Otherwise, the constructors of
Tare considered, in two phases:
All constructors that take
std::initializer_listas the only argument, or as the first argument if the remaining arguments have default values, are examined, and matched by overload resolution against a single argument of typestd::initializer_listIf the previous stage does not produce a match, all constructors of
Tparticipate in overload resolution against the set of arguments that consists of the elements of the braced-init-list, with the restriction that only non-narrowing conversions are allowed. If this stage produces an explicit constructor as the best match for a copy-list-initialization, compilation fails (note, in simple copy-initialization, explicit constructors are not considered at all).
{3} is a braced-init-list, then the vector will be initialized as containing 1 element with value 3. The behavior is consistent with passing {1, 2}, {1, 2, 3} and so on.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With