这个C代码是什么意思?

以下代码返回堆栈分配的数组的大小:

template<typename T, int size>
int siz(T (&) [size])
{
    return size;
}

但我不能围绕语法包围我的头。
特别是T(&)[size]部分…

最佳答案

but I can’t wrap my head around the syntax. Especially the T (&) [size] part…

这部分是对数组的引用。有“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
}

在上面,它声明一个具有相同的reference-to-a-array参数的函数模板,但是返回值类型为char(&)[size](这是可以理解的“左 – 右规则”的地方) 。请注意,函数调用从不在运行时发生,这就是为什么函数模板siz的定义是不必要的。 sizeof siz(x)基本上是说“如果siz(x)被调用,返回值的大小是多少”。

将数组元素计数作为编译时常数的旧C/C++方式是:

#define SIZ(arr) (sizeof(arr) / sizeof(*(arr)))

转载注明原文:这个C代码是什么意思? - 代码日志