2013-11-03 186 views
6

如何通過初始化程序列表初始化嵌套(2D)std::array用於初始化2D std :: array成員的初始化程序列表

template <std::size_t W, std::size_t H> 
class Block 
{ 
    std::array<std::array<int, W>, H> block; 
public: 

    template <typename ...E> 
    Block(E&&...e) : block {{std::forward<E>(e)...}} {} 
}; 

Block應該能夠初始化如下block成員:

Block<3, 2> b {{ {1, 2, 3}, {4, 5, 6} }}; 

注:我們必須直接在C++ 11初始化std::array的能力:

std::array<std::array<int, 3>, 2> b {{ {1, 2, 3}, {4, 5, 6} }}; 

我正在使用gcc-4.9.0

+0

通過使'block'私人和提供構造函數,'Block'現在ISN」再一次聚合。由於支撐初始化器從來沒有被推斷出來,所以現在唯一有效的初始化爲「塊<3,2>」類型的對象是'塊<3,2> b {1,2,3,4,5,6}' – dyp

+0

將它回滾到對答案有意義,然後提出一個新問題。 – Shog9

回答

5

當涉及到嵌套結構時,大括號的規則非常複雜。

在你的代碼最簡單的形式是這樣的:

Block<3, 2> b {1, 2, 3, 4, 5, 6}; 

,基本上忽略所有內部括號—這些疏漏是由語言允許的。

接下來的語法,這是稍微複雜的,是這樣的:

Block<3, 2> b {{1, 2, 3, 4, 5, 6}}; 

它仍然忽略了括號,但就Block並作爲其成員而言它完全支撐。它省略了array及其成員的括號。

而這一次是完全支撐:

Block<3, 2> b {{{ {{1, 2,3}}, {{4,5,6}} }}}; 

它括號爲所有的內部結構。

All forms compiles fine

見我詳細解釋對方回答:

1

這可能是與標準是與初始化std::array需要括號的數量過於反覆無常的解釋做。這充分支撐版本沒有問題彙編了GCC 4.8.1:

Block<3, 2> b { 
       { 
       { 
       { {1, 2, 3} }, { {4, 5, 6} } 
       } 
       } 
       }; 

奇怪的是,該版本編譯過:

Block<3, 2> b { 
       {{ {1, 2, 3}, {4, 5, 6} } } 
       }; 
+1

@MM。沒問題。它對我仍然沒有任何意義。無論如何,我認爲你的第一次嘗試在C++ 14中應該是合法的。 – juanchopanza