How do you create a multidimensional array (matrix) whose dimensions are determined at runtime.
The best way seems to be to take a vector of dimensions for construction and also a vector of offsets to access individual elements
This will also allow using initializer lists:
This should take a matrix of types determined at compile time, so templates make sense
C++11 features should be used as appropriate, bonus points for lambdas
Example usage:
int main(int, char **)
{
static const std::size_t d1{2};
static const std::size_t d2{3};
static const std::size_t d3{4};
multi_vec<std::size_t> q({d1,d2,d3});
for (std::size_t i1=0; i1 < d1; ++i1)
for (std::size_t i2=0; i2 < d2; ++i2)
for (std::size_t i3=0; i3 < d3; ++i3)
q[{i1,i2,i3}]=foo(i1,i2,i3);
for (std::size_t i1=0; i1 < d1; ++i1)
for (std::size_t i2=0; i2 < d2; ++i2)
for (std::size_t i3=0; i3 < d3; ++i3)
std::cout << "{"
<< i1 << ","
<< i2 << ","
<< i3 << "}=> "
<< foo(i1,i2,i3) << "=="
<< q[{i1,i2,i3}]
<< ((foo(i1,i2,i3) == q[{i1,i2,i3}])
? " good" : " ERROR")
<< std::endl;
};
You use C. Honestly, C's dynamic arrays are superior to anything C++ offers. Here is the code for a 3D array:
A 3D array is nothing more or less than a 1D array of 2D arrays (which are 1D arrays of 1D arrays in turn), so you declare a pointer
*array
to a 2D array of integersint (...)[heigh][width]
, and allocate space fordepth
such elementsmalloc(depth*sizeof(*array))
. This is fully analogous to creating a 1D array withint *array = malloc(length*sizeof(*array));
. The rest is array-pointer-decay magic.This works is C, because C allows array types to contain dynamic sizes (since C99). It's like defining two constants with the declared sizes at the point of the declaration. C++, on the other hand, still insists on array sizes being compile-time constants, and thus fails to allow you multi-dimensional arrays of dynamic size.
As answered here https://stackoverflow.com/a/19725907/2684539 :
This is actually a good place to use lambdas with
std::for_each
and unique_ptr for memory management:This uses a single dimensional array for actual storage and caches multipliers for reuse Since a normal multidimension array e.g.
x[2][3][4]
does not bounds check, going out of bounds is deemed undefined instead of constantly checking values that are probably valid. In the same way diminsionality is not checked for lookups, if required, a static member can be added to check if a parameter is valid, in terms of bounds or dimensionality.