Reputation: 33
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 c++11.
Upvotes: 3
Views: 1533
Reputation: 32722
Something similar to @KorelK 's approach. Recursive template function will stop when
class template of std::array
is primitive type.
#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
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
Reputation: 170055
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
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