Deduce array dimension from array name through C++ template metaprogramming
Asked Answered
F

2

5

I remember that ten years ago, there was a piece of code using c++ template meta programming which can deduce the array dimensions from an array name.

For example

int a[2][3][4][5][6];
cout << DimOfArray(a) << endl

Output:

5

But I forget the details of that code. I remember it uses sizeof(a)/sizeof(a[0]) tricks. Does anyone know how to write it?

Fishbowl answered 21/8, 2018 at 5:52 Comment(3)
a is a multidimensional array, which dimension should DimOfArray return?Supersaturate
Try std::rank (or std::rank_v).Coronel
Sorry, it should be 5. I will modify my question.Fishbowl
O
6

The original code might have built what today is provided by std::rank, see section "Possible implementation"; for not having to inherit from integral constant (that wouldn't have existed in those days), it could be modified to:

template<typename T>
struct rank { static size_t const value = 0U; };

template<typename T>
struct rank<T[]> { static size_t const value = rank<T>::value + 1; };

template<class T, std::size_t N>
struct rank<T[N]> { static size_t const value = rank<T>::value + 1; };

The code then would have used this template class in the template function (the template class might have been local classes in the function as well):

template <typename T>
size_t dimOfArray(T const& array)
{
    return /*std::*/rank<T>::value;
}

With modern C++ best declare this function constexpr. If you are rather after getting the size of one specific dimension, you could use this:

template <typename T, size_t N>
size_t dimOfArray(T const (&array)[N]) constexpr
{
    return N;
}

Again, today you might want to have it constexpr (as shown).

The latter (size of a specific dimension) is what you could achieve with sizeof(a)/sizeof(*a) "tricks" as well (instead of the much simpler returning of N), I don't see, though, how you'd want to get the number of dimensions with.

Overweigh answered 21/8, 2018 at 6:28 Comment(0)
A
1

Since C++11 you have std::rank, so this little wrapper will do what you want:

#include <type_traits>

template <typename T>
size_t DimOfArray(T const& array) constexpr
{
    return std::rank<T>::value;
}
Acromion answered 21/8, 2018 at 6:32 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.