2017-10-10 147 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