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 even be 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'm wondering if there is a cleaner, more C++ way to do something similar.
now
is
an alternative solutions is:
this uses the syntax:
if you prefer it.
We can even combine the two, allowing either syntax.
and now
works.
But be careful - the order is tricky!
To keep this the same we want
to be
not
here are test cases to determine if you got the order right:
remove whichever have the wrong syntax for your chosen
array_t.Live example
Now, even this might be wrong. It feels incorrect that
doesn't have sub-arrays of size 3, yet
feels like it should also be the same array, and the layout of
int[3][2]should agree witharray_t<int[3][2]>and agree witharray_t<int, 3, 2>.Also,
array_t< array_t<int, 3>, 2>should be the same asarray_t<int[3], 2>.These requirements disagree with each other. I mean, all over the place they disagree.
Probably the simplest way to resolve this is to require only
[][][]syntax, or don't permit mixed[]and,syntax.Having
array_t<int[3][2]>with the same layout asint[3][2]is high value. Similarly, havingarray_t< int, 3, 2 >syntax is high value. Probably we wantarray_t<int, 3, 2>to mean the same asint[3][2]? Throw away this being equal toarray_t< array_t<int, 3>, 2>- instead it equalsarray_t<array_t<int,2>,3>. Finally, blockarray_t<int[3], 2>syntax as confusing.Then, split the
array_t< T, 1,2,3,...>fromarray_t<T[1][2][3]...>templates to minimize confusion.