2016-07-26 28 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