但我无法理解语法。尤其是T (&) [size] 部分...
该部分是对数组的引用。有 "right-left rule" 用于破译任何 C 和 C++
声明。
因为函数模板从提供的函数参数推断模板参数类型,所以这个函数模板所做的就是推断数组的类型和元素计数并返回计数。
函数不能通过值接受数组类型,而只能通过指针或引用。引用用于避免将数组隐式转换为指向其第一个元素的指针(也称为数组衰减):
void foo(int*);
int x[10];
int* p = x; // array decay
foo(x); // array decay again
数组衰减会破坏数组的原始类型,因此它的大小会丢失。
注意,因为它是 C++03 中的函数调用,所以返回值不是编译时常量(即返回值不能用作模板参数)。在 C++11 中,该函数可以用 constexpr 标记以返回编译时间常数:
template<typename T, size_t size>
constexpr size_t siz(T(&)[size]) { return size; }
为了在 C++03 中将数组元素计数作为编译时间常数,可以使用稍微不同的形式:
template<class T, size_t size>
char(&siz(T(&)[size]))[size]; // no definition required
int main()
{
int x[10];
cout << sizeof siz(x) << '\n';
double y[sizeof siz(x)]; // use as a compile time constant 10
}
在上面它声明了一个具有相同引用数组参数的函数模板,但返回值类型为char(&)[size](这是可以理解“左右规则”的地方)。请注意,函数调用永远不会在运行时发生,这就是为什么函数模板siz 的定义是不必要的。 sizeof siz(x) 基本上是在说“如果调用siz(x),返回值的大小是多少”。
获取数组元素计数作为编译时间常数的旧 C/C++ 方法是:
#define SIZ(arr) (sizeof(arr) / sizeof(*(arr)))