2016-07-26 35 views
2

我想要一個有數組元素作爲成員的元組。特別是,我想這個數組元素是2D的 - 所以任何答案必須工作超過1D。我最喜歡的是我可以用初始化列表初始化的東西,例如std::tuple<ARRAY_TYPE, ...>({{0, 1}, {2, 3}}, ...)什麼是用數組(C或std :: array)元素構造C++元組的單行表達式?

看起來這樣的元組很難構造,需要手動初始化(即對於循環等)。這是我試過的:

std::tuple<int[M][N], ...> - 由於C風格數組的限制,這不起作用。元組本身是一個有效的類型,但初始化需要手動完成(而不是在構造中)。

std::tuple<std::array<std::array<int, M>, N>, ...> - 我認爲這會起作用,但由於某種原因,像std::tuple<std::array<std::array<int, 2>, 2>, ...>({{0, 1}, {2, 3}}, ...)之類的東西會失敗,並顯示「沒有匹配的構造函數錯誤」。它確實在1D工作。

std::tuple<std::vector<std::vector<int>>, ...>({{0, 1}, {2, 3}}, ...)實際上確實工作,但載體似乎有點小題大做這裏

任何想法,SO?有什麼辦法可以讓C風格的數組工作?這將是理想的。

+0

[This](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4387)可能是相關的,並且在C++ 17中顯然是預期的。 – Quentin

回答

7

你需要一個額外的對括號{}陣列周圍:

std::tuple<std::array<std::array<int, 2>, 2>, int> v({{{0, 1}, {2, 3}}}, 1); 
                ^   ^

這是因爲std::array使用總初始化初始化。它與std::vector一起使用,因爲有std::vector<std::initializer_list<T>構造函數(std::array沒有任何構造函數)。

+0

你當然是對的。 Upvoted。仍然希望C風格的陣列可以工作。 – user2333829

0

您可以使用std::make_tuple,例如:

auto t = std::make_tuple<std::array<std::array<int, 2>, 2>>({{{1, 2}, {3, 4}}}); 

[編輯] 我原來的建議是:

auto t = std::make_tuple<int[2][2], int>({{1, 2}, {3, 4}}, 42); 

但它是不安全的(第一個元組元素將指向堆棧存儲器);見下面的討論。

+0

這正是我想要的!它的工作原理。但是,這是安全的嗎?返回類型是'std :: tuple '。 – user2333829

+1

我的擔心是它返回指向std :: initializer_list中數據的指針。 – user2333829

+2

@ user2333829內部類型將是'int(*)[2]',所以它不安全 - 只要嘗試從函數返回它或複製這樣的'tuple',你就會很快發現問題。 – Holt