Micha
Micha

Reputation: 33

How to find size of multidimensional std::array?

I am having a multidimensional std::array and looking for the proper (convenient and efficient) way to find its size (in number of cells or in bytes)

size() returns only the last dimension size (which is understood)

std::array<std::array<std::array<std::array<double, 2>, 3>, 6>, 100> my_array;

my_array.size();  // returns 100

Although the size of the array is known in compile time, I wish to avoid #define SIZE_OF_MY_ARRAY or a global variable because, I am looking for a better way than passing the size with the array (as in "old" arrays, not std array), or informing others to use the defined term.

I also prefer no to calculate it every time.

Perhaps these 2 preferences are not possible for multidimensional array?

How can I efficiently find the overall size of my_array? I am using .

Upvotes: 3

Views: 1533

Answers (5)

JeJo
JeJo

Reputation: 32722

Something similar to @KorelK 's approach. Recursive template function will stop when class template of std::array is primitive type.

(See online)

#include <array>
#include <type_traits> // std::is_fundamental_v

template<typename Type, std::size_t N>
std::size_t overall_size(const std::array<Type, N>&)
{
    if constexpr(std::is_fundamental_v<Type>)   return N;
    else return N * overall_size(Type{});
}

Upvotes: 2

Coral Kashri
Coral Kashri

Reputation: 3506

You can use a recursion to calculate its size:

template<typename T>
size_t get_array_full_size(T &val) { // for the last array type (double in this case)
    return 1;
}

template<typename T, size_t Len>
size_t get_array_full_size(std::array<T, Len> &arr) {
    return get_array_full_size(arr[0]) * arr.size();
}

int main() {
    std::array<std::array<std::array<std::array<double, 2>, 3>, 6>, 100> my_array;
    std::cout << get_array_full_size(my_array) << std::endl;
    return 0;
}

Upvotes: 3

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.

Upvotes: 3

Arne
Arne

Reputation: 1338

How about

sizeof(my_array)/sizeof(double);

Upvotes: 2

lubgr
lubgr

Reputation: 38267

You could use constexpr variables that bind to the dimensions and then use those to compute the desired quantity.

constexpr int n1 = 2;
constexpr int n2 = 3;
constexpr int n3 = 6;
constexpr int n4 = 100;

std::array<std::array<std::array<std::array<double, n1>, n2>, n3>, n4> my_array;

constexpr int myArraySize = n1*n2*n3*n4;

Upvotes: 1

Related Questions