2011-11-19 174 views
46

除非我錯了,應該是可以創建一個std:陣列在以下方面:使用std ::數組初始化列表

std::array<std::string, 2> strings = { "a", "b" }; 
std::array<std::string, 2> strings({ "a", "b" }); 

然而,使用GCC 4.6.1,我無法得到任何這些工作。編譯器只是說:

expected primary-expression before ',' token 

然而初始化列表工作正常與std :: vector。那它是哪一個?我誤以爲std :: array應該接受初始化列表,還是讓GNU標準C++庫團隊瘋狂?

+0

墜毀鐺...... – Dani

+0

我不知道這是否應該工作(我不掌握最新的0X的東西),但是,錯誤或不,我認爲這是因爲使用了'性病: :字符串與字符串文字。你有沒有嘗試用'std :: string()'包裝字符串文字? –

+0

@Chris:這適用於Mac OSX 10.6上的gcc 4.6.1。你使用什麼編譯器選項? – juanchopanza

回答

72

std::array是有趣的。它基本上是這樣定義的:

template<typename T, int size> 
struct std::array 
{ 
    T a[size]; 
}; 

它是一個包含數組的結構。它沒有一個帶初始化列表的構造函數。但std::array是由C++ 11的規則聚合而成的,因此它可以通過聚合初始化來創建。要聚合初始化內部陣列的結構,需要第二組花括號:

std::array<std::string, 2> strings = {{ "a", "b" }}; 

注意,標準確實表明額外的支撐可以在這種情況下被省略。所以它可能是一個GCC錯誤。

+0

標準委員會是否故意這樣做? – Dani

+0

爲什麼標準不要求'std :: array'有一個可以與初始化列表一起工作的構造函數? –

+6

@PaulManta:因爲那樣它就不符合聚合初始化的條件。根據數組元素的類型(std :: string不符合條件),彙總初始化可以在編譯時摺疊。無論數組元素的類型如何,初始化程序列表初始化* must *都是運行時函數調用。 –

9

要添加到接受的答案:

std::array<char, 2> a1{'a', 'b'}; 
std::array<char, 2> a2 = {'a', 'b'}; 
std::array<char, 2> a3{{'a', 'b'}}; 
std::array<char, 2> a4 = {{'a', 'b'}}; 

在GCC 4.6.3(Xubuntu上12.01)的所有工作。然而,

void f(std::array<char, 2> a) 
{ 
} 

//f({'a', 'b'}); //doesn't compile 
f({{'a', 'b'}}); 

以上需要雙大括號來編譯。在下面的錯誤單括號結果版本:

../src/main.cc: In function ‘int main(int, char**)’: 
../src/main.cc:23:17: error: could not convert ‘{'a', 'b'}’ from ‘<brace-enclosed initializer list>’ to ‘std::array<char, 2ul>’ 

我不知道哪方面類型推斷/轉換使事情以這種方式工作,或者如果這是GCC的實現的怪癖。