2017-02-06 50 views
4

我想用對象列表初始化向量或數組。它適用於載體中,但不適用於數組:爲什麼大括號初始化列表不適用於std :: array

struct Widget 
{ 
    string name; 
    vector<int> list; 
}; 

struct Object 
{ 
    string name; 
    vector<int> list; 
    Object(string _name, vector<int> _list) : name(_name), list(_list) { } 
}; 

int main() 
{ 
    const vector<Widget> vw = { 
     {"vw1", {1,2,3}}, 
     {"vw2", {1,2,3}} }; 
    const array<Widget,2> aw = { 
     {"aw1", {1,2,3}}, 
     {"aw2", {1,2,3}} }; 
    const vector<Object> vo = { 
     {"vo1", {1,2,3}}, 
     {"vo2", {1,2,3}} }; 
    const array<Object,2> ao = { 
     {"ao1", {1,2,3}}, 
     {"ao2", {1,2,3}} }; 
    return 0; 
} 

從鐺錯誤:

widget.cpp:36:9: error: excess elements in struct initializer 
     {"aw2", {1,2,3}} }; 
     ^~~~~~~~~~~~~~~~ 
widget.cpp:41:10: error: no viable conversion from 'const char [4]' to 'Object' 
     {"ao1", {1,2,3}}, 
     ^~~~~ 
widget.cpp:41:17: error: no matching constructor for initialization of 'Object' 
     {"ao1", {1,2,3}}, 
       ^~~~~~~ 

是什麼矢量和陣列之間的差異,這防止了陣列型從支持此語法?

+0

我不是100%確定,但我相信這是一個奇怪的互動集合初始化和大括號初始化列表之間。它可以按照以下答案中的描述來解決,但我不確定問題的具體原因是什麼。仔細檢查錯誤消息表明,該陣列「吸收」了額外的支撐,無論如何,缺乏更好的術語;注意它是如何認爲''ao1'和'{1,2,3}'是兩個不同的'Object',而不是同一個'Object'的初始化列表的一部分 –

回答

4

這裏是工作解決方案 - 你需要數組的雙括號。

int main() 
{ 
    const vector<Widget> vw = { 
     {"vw1", {1,2,3}}, 
     {"vw2", {1,2,3}} }; 
    const array<Widget,2> aw = {{ 
     {"aw1", {1,2,3}}, 
     {"aw2", {1,2,3}} }}; 
    const vector<Object> vo = { 
     {"vo1", {1,2,3}}, 
     {"vo2", {1,2,3}} }; 
    const array<Object,2> ao = {{ 
     {"ao1", {1,2,3}}, 
     {"ao2", {1,2,3}} }}; 
    return 0; 
} 

爲什麼?

http://en.cppreference.com/w/cpp/container/array

的std ::陣列是一個封裝固定大小的陣列的容器。 這個容器是一個聚合類型,其語義與持有C樣式數組T [N]作爲其唯一非靜態數據成員的結構相同。不像C風格的數組,它不會自動衰減到T *。作爲一個聚合類型,它可以初始化爲聚合初始化,最多賦予N個初始化器,這些初始化器可轉換爲T:std :: array a = {1,2,3} ;.

理論的實現(這在現實中是比較複雜)

template <typename T, size_t size> 
struct array 
{ 
    T data[size]; 
} 

所以第一支撐是聚集-initializate數組對象自身,第二支柱聚集-initializate內部的「傳統的C式」陣列。

+0

這很有趣,它們有很多大括號...但有意義的是什麼書面。也鏈接的問題/答案有幫助。謝謝! –

0

添加另外一對大括號到您的實例,使他們能夠正常工作:

int main() 
{ 
    const std::array<Widget,2> aw = { 
     { 
      {"aw1", {1, 2, 3}}, 
      {"aw2", {1, 2, 3}} 
     } 
    }; 

    const std::array<Object, 2> ao = { 
     { 
      {"ao1", {1, 2, 3} }, 
      {"ao2", {1, 2, 3} } 
     } 
    }; 

    cout << aw[0].name << " " << aw[1].list[1] << endl; 
    cout << ao[0].name << " " << ao[1].list[1] << endl; 

    return 0; 
} 

會給輸出:

aw1 2 
ao1 2 

額外的一對大括號,需要爲std::array沒有構造函數本身,只是使用聚合初始化而不是列表初始化。

在實施方面,std::array由一個內部項目組成,這是一個真實的基本數組N元素。因此,我們需要額外的大括號,所以我們初始化std::array一個元素(這是一個在你的例子中,兩個元素的數組)

相關問題