Initializing vector with double curly brac

2019-05-07 19:30发布

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

1条回答
Bombasti
2楼-- · 2019-05-07 20:09

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.

查看更多
登录 后发表回答