I’m about to convert a lot of old C++ code to more modern C++.
There are many raw 2D arrays in that code like:
Foo bar[XSIZE][YSIZE];
And I’m about to replace these declarations with
std::array<std::array<Foo, YSIZE>, XSIZE> bar;
This is a convenient way because the statements stay the same and the code is supposed to behave the same as with raw arrays with the additional benefit of being able to have out of bounds checks in debug builds.
But IMO the std::array<std::array<Foo, YSIZE>> is somewhat cumbersome and not easy to read, and with 3D arrays (although I have none) it would be even worse.
Right now I’m using this macro to make the declaration more readable:
#define DECLARE_2D_ARRAY(type, x, y) std::array<std::array<type, y>, x>
...
DECLARE_2D_ARRAY(Foo, XSIZE, YSIZE) bar;
But I feel this to be a macro hack, and I wonder if there is a cleaner, more C++ way to do something similar.
>Solution :
template<class A>
struct std_array_helper {
using type=A;
};
template<class A>
using array_t = typename std_array_helper<A>::type;
template<class T, std::size_t N0>
struct std_array_helper<T[N0]> {
using type=std::array<array_t<T>, N0>;
};
now
array_t<Foo[XSIZE][YSIZE]>
is
std::array< std::array<Foo, XSIZE>, YSIZE>
an alternative solutions is:
template<class T, std::size_t...Sz>
struct array_helper {
using type=T;
};
template<class T, std::size_t N0, std::size_t...Ns>
struct array_helper<T,N0>:
array_helper<std::array<T, N0>, Ns...>
{};
template<class T0, std::size_t...Ns>
using array_t = typename array_helper<T0, Ns...>::type;
this uses the syntax:
array_t<Foo, XSIZE, YSIZE>
if you prefer it.
We can even combine the two, allowing either syntax.