Just a comment on Mykola's answer:
Arrays are not pointers, even if they tend to decay into pointers really easily. The compiler has more info on an array than on a container:
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; // will print 4
std::cout
<< std::accumulate( array::begin( theArray ), array::end( theArray ), 0, std::plus<int>() )
<< std::endl; // will print 10
}
While you cannot ask about the size of the array, the compiler will resolve it when calling the given templates.
Now, if you call a function that takes a int a[]
(note that there is no size), that is similar to defining an int*
parameter, and the size info is lost in the way. The compiler will not be able to determine the size of the array inside the function: the array has decayed into a pointer.
If , on the other hand, you define the parameter as int a[10]
then the information is lost, but you will not be able to call the function with an array of a different size. This is completely different than the C version, at least prior to C99 have not checked lately[*]. In C the compiler will ignore the number in the argument and the signature will be equivalent to the previous version.
@litb: You are right. I had this test around, but it is with a reference to an array, not with an array. Thanks for pointing it out.
dribeas@golden:array_size$ cat test.cpp
void f( int (&x)[10] ) {}
int main()
{
int array[20];
f( array ); // invalid initialization of reference of type 'int (&)[10]' from...
}