Multidimensional Std::Array

Multidimensional std::array

You need extra brackets, until c++14 proposal kicks in.

std::array<std::array<int, 3>, 3> arr = {{{5, 8, 2}, {8, 3, 1}, {5, 3, 9}}};

How to create a multi dimensional std::array using a template?

Certainly possible with use of helper class templates, C++11 (except the static assert part)

#include <array>

template<typename T, std::size_t Head, std::size_t... Tail>
struct MDA_impl{
using type = std::array<typename MDA_impl<T, Tail...>::type, Head>;
};
// Base specialization
template<typename T, std::size_t N>
struct MDA_impl<T,N>{
using type = std::array<T, N>;
};

template<typename T, std::size_t... Ns>
using MDA = typename MDA_impl<T,Ns...>::type;

int main(){
static_assert(std::is_same_v<MDA<int,3,4,5,6>,
std::array<std::array<std::array<std::array<int, 6>,5>,4>,3>>);
}

how do I declare a 2d std::array

std::array is 1-dimensional, there is no such thing as a 2-dimensional std::array. You would simply have to use an inner std::array as the element type of an outer std::array, eg:

#include <iostream>
#include <array>

int main(){
std::array<std::array<int,5>,4> myarray;
for (int i=0; i<5; i++){
for (int j=0; j<10; j++){
myarray[i].at(j) = j+1;
}
}
}

less verbose way to declare multidimensional std::array

When nested, std::array can become very hard to read and unnecessarily verbose. The opposite ordering of the dimensions can be especially confusing.

For example:

std::array < std::array <int, 3 > , 5 > arr1; 

compared to

char c_arr [5][3]; 

Also, note that begin(), end() and size() all return meaningless values when you nest std::array.

For these reasons I've created my own fixed size multidimensional array containers, array_2d and array_3d. They have the advantage that they work with C++98.

They are analogous to std::array but for multidimensional arrays of 2 and 3 dimensions. They are safer and have no worse performance than built-in multidimensional arrays. I didn't include a container for multidimensional arrays with dimensions greater than 3 as they are uncommon. In C++11 a variadic template version could be made which supports an arbitrary number of dimensions (Something like Michael Price's example).

An example of the two-dimensional variant:

//Create an array 3 x 5 (Notice the extra pair of braces) 
fsma::array_2d <double, 3, 5> my2darr = {{
{ 32.19, 47.29, 31.99, 19.11, 11.19},
{ 11.29, 22.49, 33.47, 17.29, 5.01 },
{ 41.97, 22.09, 9.76, 22.55, 6.22 }
}};

Full documentation is available here:
http://fsma.googlecode.com/files/fsma.html

You can download the library here:
http://fsma.googlecode.com/files/fsma.zip

c++ std multidimensional array memory layout

int simple_2D_array[M][N];

This is guaranteed to be contiguous in memory. You can use pointer arithmetic to calculate the position of any index relative to the start.

std::array<std::array<int,N>,M> std_2D_array;

This, in general, does not have to be contiguous in memory. It is an array of objects, each of which happens to be an array. While each of the internal arrays is logically equivalent to a C-style array as its only non-static data member, it is permissible for the compiler to decide that the entire internal array requires padding.

So, in practice, it is probably contiguous, but it probably doesn't pay to rely on that. Just write an iterator or something.

How to find size of multidimensional std::array?

It's not too hard to write a small utility that calculates this at compile time.

template<typename T> struct arr_sz {
static constexpr std::size_t size = sizeof(T);
};

template<typename T, std::size_t N>
struct arr_sz<std::array<T, N>> {
static constexpr std::size_t size = N * arr_sz<T>::size;
};

The above should unravel a nested array definition of any practical depth, and evaluate to the size in bytes used for storing T's, with all potential padding excluded.

An example of using it would be

std::array<std::array<std::array<std::array<double, 2>, 3>, 6>, 100> my_array;
constexpr auto sz = arr_sz<decltype(my_array)>::size;
static_assert(sz == sizeof(double) * 2 * 3 * 6 * 100, "");

That you may see live.



Related Topics



Leave a reply



Submit