关于Mykola的回答,我想发表一些评论:(链接)
数组并不是指针,即使它们很容易退化为指针。编译器对数组比容器有更多的信息:
namespace array {
template <typename T, int N>
size_t size( T (&a)[N] ) {
return N;
}
template <typename T, int N>
T* begin( T (&a)[N] ) {
return &a[0];
}
template <typename T, int N>
T* end( T (&a)[N] ) {
return &a[N];
}
}
int main()
{
int theArray[] = { 1, 2, 3, 4 };
std::cout << array::size( theArray ) << std::endl;
std::cout
<< std::accumulate( array::begin( theArray ), array::end( theArray ), 0, std::plus<int>() )
<< std::endl;
}
虽然您不能询问数组的大小,但编译器在调用给定的模板时会解决它。
如果您调用一个采用
int a[]
(注意没有大小)的函数,那么这类似于定义一个
int*
参数,大小信息会丢失。编译器无法在函数内确定数组的大小:数组已经衰变为指针。
如果您将参数定义为
int a[10]
,则信息也会丢失
,但您将无法使用不同大小的数组调用该函数。这与 C 版本完全不同,至少在 C99 之前我没有检查过[*]。在 C 中,编译器将忽略参数中的数字,并且签名将等同于先前的版本。
@litb:您是正确的。我有这个测试,但它带有对数组的引用,而不是数组本身。感谢指出。
dribeas@golden:array_size$ cat test.cpp
void f( int (&x)[10] ) {}
int main()
{
int array[20];
f( array );
}