Here is a demonstrative program where there are declared two functions that both accept a reference to an array.
#include <iostream>
void f( const int ( &a )[5] )
{
std::cout << "void f( const int ( &a )[5] )\n";
}
void f( const int ( &a )[6] )
{
std::cout << "void f( const int ( &a )[6] )\n";
}
int main()
{
f( { 1, 2, 3 } );
return 0;
}
As it is seen the first function declaration is
void f( const int ( &a )[5] );
and the second function declarations is
void f( const int ( &a )[6] );
And the function call expression is
f( { 1, 2, 3 } );
Trying to compile this program using the compiler C++14 (gcc 8.3)
at www,ideone.com I get the error
prog.cpp:15:17: error: call of overloaded ‘f(<brace-enclosed initializer list>)’ is ambiguous
f( { 1, 2, 3 } );
^
prog.cpp:3:6: note: candidate: ‘void f(const int (&)[5])’
void f( const int ( &a )[5] )
^
prog.cpp:8:6: note: candidate: ‘void f(const int (&)[6])’
void f( const int ( &a )[6] )
Is the program incorrect?
The program is correct. It is a bug of the compiler.
According to the C++ 14 Standard (13.3.3.2 Ranking implicit conversion sequences)
3 Two implicit conversion sequences of the same form are indistinguishable conversion sequences unless one of the following rules applies:
(3.1) — List-initialization sequence L1 is a better conversion sequence than list-initialization sequence L2 if
(3.1.2) — L1 converts to type “array of N1 T”, L2 converts to type “array of N2 T”, and N1 is smaller than N2, even if one of the other rules in this paragraph would otherwise apply.
Thus according to the quote the overloaded function
void f( const int ( &a )[5] );
will be called.