[英]What does this C++ code mean?
以下代码返回堆栈分配的数组的大小:
template<typename T, int size>
int siz(T (&) [size])
{
return size;
}
但我无法理解语法。 特别是T (&) [size]
部分......
但我无法理解语法。 特别是
T (&) [size]
部分......
该部分是对数组的引用。 有解释任何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)))
T (&) [size]
是对数组的引用。 它需要作为参考,因为以下程序是不合法的:
#include <iostream>
int sz(int *) { std::cout << "wtf?" << std::endl; return 0; }
int sz(int [4]) { std::cout << "4" << std::endl; return 0; }
int main() {
int test[4];
sz(test);
}
该程序无法编译:
test.cc: In function ‘int sz(int*)’:
test.cc:6:5: error: redefinition of ‘int sz(int*)’
test.cc:3:5: error: ‘int sz(int*)’ previously defined here
因为int sz(int [4])
与int sz(int *)
。
括号需要在这里消除歧义,因为T& [size]
看起来像一个引用数组,否则是非法的。
通常如果参数不是匿名的,你会写:
template<typename T, int size>
int sz(T (&arr) [size])
为数组赋予名称arr
。 在这种情况下,尽管所有关注的示例代码都是推导出的大小,因此匿名参数避免了有关未使用参数的警告。
它是一个函数,它成为一个typename(模板可以与不同的类型名一起使用)和一个来自外部的大小。 然后它返回此大小。
堆栈函数通常使用size
,这是一个整数,用于显示使用此函数请求的堆栈大小。 &
测试堆栈T的大小是什么意思。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.