我会尽量用简单的方式解释。
使用std::rank,您想知道数组类型的维数,其中非数组被视为零维数组。
给定一个类型T,你有三种情况:
-
T 不是数组
-
T 是另一个类型U 的元素的“未知边界数组”(参见this page),这是一个未知大小的数组,我们可以表示为U[],其中U 是其他类型
-
T 是已知大小的数组 N 类型为 U 的元素,我们可以将其表示为 U[N],其中 U 是另一种类型。
在情况 2 和 3 中,子类型 U 可以是数组,也可以不是数组,所以游戏重新开始。
查看我在案例 2 和 3 中使用 U 而不是 T 重写的“可能实现”
// case 1: T isn't an array
template<class T>
struct rank
: public std::integral_constant<std::size_t, 0>
{ };
// case 2: T is an array of unknown bound (U[])
template<class U>
struct rank<U[]>
: public std::integral_constant<std::size_t, rank<U>::value + 1>
{ };
// case 3: T is an array on size N (U[N])
template<class U, std::size_t N>
struct rank<U[N]>
: public std::integral_constant<std::size_t, rank<U>::value + 1>
{ };
当你在非数组类型T 时请求std::rank<T>::value 时,唯一匹配的rank 版本是第一个,所以value 为零(继承自std::integral_constant<std::size_t, 0>)。
相反,当T 是数组类型时,当您要求std::rank<T>::value 时(假设T 是int[3],那么U 是int 和N 是3)有两个匹配std::rank<T> 的rank 版本:第一个(主要的,非专业化的)和两个部分专业化之一)。但是 C++ 的规则强制编译器选择最专用的版本,所以选择在std::rank<U>::value 处添加1 的专用版本(第三个版本,在int[3] 的情况下)。
一个实际的例子
std::rank<int[1][2][3]>::value
== 1 + std::rank<int[1][2]>::value
== 1 + 1 + std::rank<int[1]>::value
== 1 + 1 + 1 + std::rank<int>::value
== 1 + 1 + 1 + 0
== 3