2017-10-10 67 views
4

有人可以解释下面示例中初始化双花括号和单花括号之间的行为差​​异吗?使用双曲花括号初始化矢量<string>

代码#1:

vector<string> v = {"a", "b"}; 
string c(v[0] + v[1]); 
cout << "c = " << c; 
cout << "c.c_str() = " << c.c_str(); 

输出#1:

c = ab 
c.c_str() = ab 

代码#2:

vector<string> v = {{"a", "b"}}; 
string c(v[0] + v[1]); 
cout << "c = " << c; 
cout << "c.c_str() = " << c.c_str(); 

输出#2:

c = a\acke�Z\ 
c.c_str() = a 
+0

我测试代码#2并抛出异常行:'vector v = {{“a”,“b”}};' – aghilpro

回答

7

隐式转换中央。这就是发生了什么事。

  1. vector<string> v = {"a", "b"};您通过提供元素的初始化列表初始化向量。这两个std::string从字符串文字初始化,然后复制到矢量中。

  2. vector<string> v = {{"a", "b"}};您通过提供带有元素的初始化程序来初始化矢量。并且该单个std::string从具有两个元素的初始化器初始化。访问矢量的第二个元素具有未定义的行为。

现在,这里有趣的部分。即使在您访问v[1]之前,您的第二个片段仍有未定义的行为。重载解析(构造单个std::string)挑选构造函数。最好可行之一,是这样的:

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

随着InputIt被推导出char const [2](和功能参数调节,它转向char const*)。由于这些不是真正的迭代器,所有地狱都打破了。

+0

请参阅https://stackoverflow.com/questions/46665914/vector-initialization -with-double-curly-braces-stdstring-vs-int也许你可以解释这种差异 – bolov