Can someone explain the difference in behavior between initializing with double and single curly braces in the example below?
Code #1:
vector<string> v = {"a", "b"};
string c(v[0] + v[1]);
cout << "c = " << c;
cout << "c.c_str() = " << c.c_str();
Output #1:
c = ab
c.c_str() = ab
Code #2:
vector<string> v = {{"a", "b"}};
string c(v[0] + v[1]);
cout << "c = " << c;
cout << "c.c_str() = " << c.c_str();
Output #2:
c = a\acke�Z\
c.c_str() = a
Implicit conversion central. That's what's going on.
vector<string> v = {"a", "b"};
You initialize the vector by providing an initializer list with two elements. The twostd::string
s are initialized from the string literals, and then copied into the vector.vector<string> v = {{"a", "b"}};
You initialize the vector by providing an initializer with one element. And that singlestd::string
is initialized from an initializer that has two elements. Accessing the second element of the vector has undefined behavior.Now, here's the fun part. Your second snippet has undefined behavior even before you access
v[1]
. Overload resolution (to construct the singlestd::string
) picks a constructor. The best viable one, is this:With
InputIt
being deduced aschar const [2]
(and function parameter adjustment, turning it tochar const*
). Since those aren't really iterators, all hell breaks loose.