Search code examples
c++c++11stlstdarraystdtuple

What is a one-line expression for constructing a C++ tuple with an array (C or std::array) element?


I'd like to have a tuple that has an array element as a member. In particular, I'd like this array element to be 2D -- so any answer has to work for more than 1D. What I'd ideally like is something I can initialize with initializer lists, e.g. std::tuple<ARRAY_TYPE, ...>({{0, 1}, {2, 3}}, ...).

It seems like such a tuple is very hard to construct, requiring manual initialization (i.e., for loops and the like). Here is what I've tried:

std::tuple<int[M][N], ...> -- this doesn't work because of limitations of C-style arrays. The tuple itself is a valid type, but initialization needs to be done manually (not at construction).

std::tuple<std::array<std::array<int, M>, N>, ...> -- I thought this would work, but for some reason, something like std::tuple<std::array<std::array<int, 2>, 2>, ...>({{0, 1}, {2, 3}}, ...) fails with a "no matching constructor error". It does work in 1D though.

std::tuple<std::vector<std::vector<int>>, ...>({{0, 1}, {2, 3}}, ...) actually does work, but vectors seem like overkill here

Any thoughts, SO? Is there any way I can get the C-style arrays to work? That would be ideal.


Solution

  • You need an extra pair of brackets {} around the array:

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

    This is because std::array is initialized using aggregate-initialization. It works with std::vector because there is std::vector<std::initializer_list<T> constructor (std::array does not have any constructors).