You can specify a complete array type parameter as for example
void f( int ( &a )[N] );
and within the function you will know the number of elements in the passed array.
When the function is declared like
void f( int a[] );
then the compiler adjusts the function declaration like
void f( int *a );
and you are unable to determine the number of elements in the passed array. So you need to specify a second parameter like
void f( int *a, size_t n );
Also functions with a referenced array parameter type may be overloaded. For example these two declarations
void f( int ( &a )[] );
and
void f( int ( &a )[2] );
declare two different functions.
And functions with a referenced array parameter type may be called with a braced list (provided that the corresponding parameter has the qualifier const) like for example
f( { 1, 2, 3 } );
Here is a demonstration program
#include <iostream>
void f( const int ( &a )[] )
{
std::cout << "void f( const int ( & )[] ) called.\n";
}
void f( const int ( &a )[2] )
{
std::cout << "void f( const int ( & )[2] ) called.\n";
}
void f( const int a[] )
{
std::cout << "void f( const int [] ) called.\n";
}
int main()
{
f( { 1, 2, 3 } );
}
The program output is
void f( const int ( & )[] ) called.
f__) and names that begin with an underscore followed by a capital letter are reserved for use by the implementation. Don't use them in your code.