如何在模板专业化中检测 C 风格的多维数组?
How to detect C-style multidimensional arrays in templates specialization?
我有以下代码:
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;
};
现在,我想添加另一个专门用于检测 C 风格的多维数组,即 T[a][b]...
。
实现这个的语法是什么?我可以使用 Variadic 模板吗?
我希望出现以下行为:
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
}
只需添加多维数组的特化:
template<class T, std::size_t N1, std::size_t N2>
struct detect_carray<T[N1][N2]>{
constexpr static int kind=multi_carray;
};
然后
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
顺便说一句:对于 double[3][5]
,T
将是 double
(N1
将是 3
,N2
将是 5
).对于 std::complex<double>[3][5][8][16]
,T
将是 std::complex<double> [8][16]
(N1
将是 3
,N2
将是 5
)。
标准库中已经有一个名为 std::rank
的特征,所以解决方案很简单:
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;
}
}();
};
我有以下代码:
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;
};
现在,我想添加另一个专门用于检测 C 风格的多维数组,即 T[a][b]...
。
实现这个的语法是什么?我可以使用 Variadic 模板吗?
我希望出现以下行为:
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
}
只需添加多维数组的特化:
template<class T, std::size_t N1, std::size_t N2>
struct detect_carray<T[N1][N2]>{
constexpr static int kind=multi_carray;
};
然后
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
顺便说一句:对于 double[3][5]
,T
将是 double
(N1
将是 3
,N2
将是 5
).对于 std::complex<double>[3][5][8][16]
,T
将是 std::complex<double> [8][16]
(N1
将是 3
,N2
将是 5
)。
标准库中已经有一个名为 std::rank
的特征,所以解决方案很简单:
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;
}
}();
};