这个C++代码是什么意思?
下面的代码返回一个堆栈分配数组的大小:这个C++代码是什么意思?
template<typename T, int size>
int siz(T (&) [size])
{
return size;
}
,但我不能换我的头周围的语法。 特别是T (&) [size]
部分...
但我无法用头来包装语法。特别是
T (&) [size]
部分...
该部分是对数组的引用。破译任何C和C++ 声明有"right-left rule"。
因为函数模板从所提供的函数参数中推导出模板参数类型,该函数模板所做的是推导数组的类型和元素计数并返回计数。
函数不能通过值接受数组类型,而只能通过指针或引用接受数组类型。参考用于避免其第一元件(也称为阵列衰减)的阵列的指针的隐式转换:
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)))
是什么和必要的parens? –
@JasonS - 为了避免看起来像引用'T' – Flexo
啊,好吧...和'(T&)[size]''也不起作用? (对不起,没有C编译器启动并运行) –
It's成为类型名的函数(模板可以具有不同typenames使用)和外部的大小。然后它返回这个大小。
堆栈函数经常使用size
,这是一个整数,它显示了您使用此函数请求的堆栈大小的大小。 &
测试堆栈T的大小。
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
。在这个例子中,虽然你所关心的所有示例代码都是推导的大小,因此匿名参数可以避免关于未使用参数的警告。
[为什么要在C++中以这种令人困惑的方式定义的“引用数组”)(http://stackoverflow.com/questions/6456253/why-is-reference-to-array-defined-in-这样易混淆的方式) – sharptooth
不完全重复 –
您可能想要使用别名模板并编写可能更易于阅读的别名“”。 –