I have the following code:
enum type_kind{unkown=-1,carray, multi_carray};
template<class T>
struct detect_carray{
constexpr static int kind=unkown;
};
template<class T, std::size_t N>
struct detect_carray<T[N]>{
constexpr static int kind=carray;
};
Now, I want to add another specialization for detecting multidimensional arrays in C-style, that is, T[a][b]...
.
What is the syntax to achieve this? Can I use Variadic templates?
I expect the following behavior:
int main()
{
std::cout<<detect_carray<std::vector<int>>::kind;//-1
std::cout<<detect_carray<int[3]>::kind;//0
std::cout<<detect_carray<double[3][5]>::kind;//1
std::cout<<detect_carray<std::complex<double>[3][5][8][16]>::kind;//1
//Correct out: -1011
}
CodePudding user response:
There's already a trait called std::rank
in the standard library so the solution is quite simple:
template <class T>
struct detect_carray {
enum type_kind { unknown = -1, carray, multi_carray };
static constexpr int kind = [] {
switch (std::rank_v<T>) {
case 0: return unknown;
case 1: return carray;
default: return multi_carray;
}
}();
};
CodePudding user response:
Just add a specialization for multidimensional arrays:
template<class T, std::size_t N1, std::size_t N2>
struct detect_carray<T[N1][N2]>{
constexpr static int kind=multi_carray;
};
then
std::cout<<detect_carray<std::vector<int>>::kind;//-1
std::cout<<detect_carray<int[3]>::kind;//0
std::cout<<detect_carray<double[3][5]>::kind;//1
std::cout<<detect_carray<std::complex<double>[3][5][8][16]>::kind;//1
BTW: For double[3][5]
, T
will be double
(and N1
will be 3
and N2
will be 5
). For std::complex<double>[3][5][8][16]
, T
will be std::complex<double> [8][16]
(and N1
will be 3
and N2
will be 5
).