25

Defining multi-dimensional array using the T[][][] syntax is easy. However, this creates a raw array type which doesn't fit nicely into modern C++. That's why we have std::array since C++11. But the syntax to define a multi-dimensional array using std::array is quite messy. For example, to define a three-dimensional int array, you would have to write std::array<std::array<std::array<int, 5>, 5>, 5>. The syntax doesn't scale at all. I'm asking for a fix for this issue. Maybe, this issue cannot be fixed using existing utility provided by C++. In that case, I'm happy with a custom tool developed to ease the syntax.

Found a solution myself:

template <typename T, std::size_t n, std::size_t... ns>
struct multi_array {
  using type = std::array<typename multi_array<T, ns...>::type, n>;
};

template <typename T, std::size_t n>
struct multi_array<T, n> {
  using type = std::array<T, n>;
};

template <typename T, std::size_t... ns>
using multi_array_t = typename multi_array<T, ns...>::type;

Wondering whether the implementation can be further simplified.

Lingxi
  • 14,579
  • 2
  • 37
  • 93
  • @AngryLettuce I think that would be a little too heavy for simple matters like this. I don't want to pull in a whole Boost just for this. – Lingxi Jan 26 '16 at 06:33
  • Are `typedef`'s not acceptable: `typedef std::array< std::array< std::array > > threeD;` .. `threeD arr; arr[0][0][0] ...`? This example would have to be modified to allow for different types, obviously, but curious if that might help? – txtechhelp Jan 26 '16 at 06:34
  • 3
    You could use the approach in the answers of the question at http://stackoverflow.com/questions/24463356/c11-variadic-programming-how-to-define-a-tower-of-vectors. – R Sahu Jan 26 '16 at 06:38
  • 2
    Also http://stackoverflow.com/q/7689288/636019 – the same question, but tagged `c++11`. – ildjarn Jan 26 '16 at 06:53
  • 2
    Note that the memory layout of a nested `std::array` isn't guaranteed to be the same as that of a C=style array of arrays (at least in C++11, I'm not sure if that got fixed in C++14.) – juanchopanza Jan 26 '16 at 07:01
  • @juanchopanza Isn't `std::array` just a simple wrapper around raw array? – Lingxi Jan 26 '16 at 07:03
  • 1
    @Lingxi But the standard allows it to have some padding at the end (or at least it did in C++11.) – juanchopanza Jan 26 '16 at 07:05
  • Main difficulty is access using indices. – Tomilov Anatoliy Jan 27 '16 at 14:34
  • @juanchopanza Nested std::array are stored in contiguous mem locations. See https://stackoverflow.com/a/47121087/3820989 – Mandeep Singh Aug 19 '19 at 16:48
  • @MandeepSingh Yes. My comment still stands. – juanchopanza Aug 19 '19 at 18:23
  • @juanchopanza Ah yes, you are right, read your comment again and you are not talking about contiguous mem location but probably about padding which might occur :) – Mandeep Singh Aug 20 '19 at 08:28

1 Answers1

12

Refer to Multi-dimensional arrays in C++11

template <class T, std::size_t I, std::size_t... J>
struct MultiDimArray 
{
  using Nested = typename MultiDimArray<T, J...>::type;
  // typedef typename MultiDimArray<T, J...>::type Nested;
  using type = std::array<Nested, I>;
  // typedef std::array<Nested, I> type;
};

template <class T, std::size_t I>
struct MultiDimArray<T, I> 
{
  using type = std::array<T, I>;
  // typedef std::array<T, I> type;
};

MultiDimArray<float, 3, 4, 5, 6, 7>::type floats;

MultiDimArray is a pair of meta-functions to compute nested type for multi-dimensional std::array. The most general MultiDimArray is a variadic template of unsigned integers to pass an arbitrary number of dimensions. The terminating MultiDimArray specialization defines the simplest case of single dimensional std::array.

user703016
  • 37,307
  • 8
  • 87
  • 112
zangw
  • 43,869
  • 19
  • 177
  • 214
  • Could the implementation be further simplified? – Lingxi Jan 26 '16 at 07:04
  • 1
    Its usage can be a tiny bit more improved by using template alias on top of it: `template using MultiDimArray_t = typename MultiDimArray::type; MultiDimArray_t floatArr;` – Mandeep Singh Aug 19 '19 at 16:41