Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Initializing vector<string> with double curly braces

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
like image 487
Shir Avatar asked Oct 10 '17 10:10

Shir


1 Answers

Implicit conversion central. That's what's going on.

  1. vector<string> v = {"a", "b"}; You initialize the vector by providing an initializer list with two elements. The two std::strings are initialized from the string literals, and then copied into the vector.

  2. vector<string> v = {{"a", "b"}}; You initialize the vector by providing an initializer with one element. And that single std::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 single std::string) picks a constructor. The best viable one, is this:

template< class InputIt >
basic_string( InputIt first, InputIt last, 
              const Allocator& alloc = Allocator() );

With InputIt being deduced as char const [2] (and function parameter adjustment, turning it to char const*). Since those aren't really iterators, all hell breaks loose.

like image 112
StoryTeller - Unslander Monica Avatar answered Sep 20 '22 10:09

StoryTeller - Unslander Monica