Selecting an overloaded function between two functions that both have a parameter of the type reference to an array

97 Views Asked by At

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?

2

There are 2 best solutions below

0
On BEST ANSWER

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.

0
On

some compilers may give a warning at

f( { 1, 2, 3 } );

that call to function f is ambiguous. but the program should compile. and it will call the overloaded function void f( const int ( &a )[5] ); as long as function call contains array of length <=5. as soon as you introduce the 6th element in the array it will call void f( const int ( &a )[6] ); also to mention passed argument as a is unused in both the definitions. if you got no use of that argument then the below definition shall also work.

void f( const int ( & )[5] ){}