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
Does Std::Vector *Have* to Move Objects When Growing Capacity? Or, Can Allocators "Reallocate"
False Positive with Is_Copy_Constructible on Vector<Unique_Ptr>
How to Use Std::Sort with a Vector of Structures and Compare Function
Issuing System Commands in Linux from C, C++
What Does '<Cuchar>' Provide, and Where Is It Documented
Detect If Program Is Running with Full Administrator Rights
How to Delete a Non-New Object
How to Add 2 Arbitrarily Sized Integers in C++
Forward Declare a Standard Container
Why Doesn't My Template Accept an Initializer List
Converting String of 1S and 0S into Binary Value
Construct Path for #Include Directive with MACro
Argument of Type "Char *" Is Incompatible with Parameter of Type "Lpwstr"