To prevent any confusion, I very much understand the difference between arrays and pointers, the concept of decay-to-pointer, and the concept of passing an array by reference in C++, etc.
My question here is specifically about the rules used by the compiler to select a function from a set of function overload candidates, when one overload takes an array reference, and the other overload takes a pointer.
For example, suppose we have:
template <class T, std::size_t N>
void foo(const T (&arr)[N])
{
std::cout << "Array-reference overload!" << std::endl;
}
template <class T>
void foo(const T* ptr)
{
std::cout << "Pointer overload!" << std::endl;
}
If we attempt to invoke function template foo() as follows:
const char arr[2] = "A";
foo(arr);
... then my expectation would be that the first overload, the one that takes an array reference, would be selected by the compiler.
However, using GCC 4.9.2, if I compile the above code, I get an error:
test.cpp:28:9: error: call of overloaded ‘foo(const char [2])’ is ambiguous
It's unclear to me why both overloads are considered equally good candidates by the compiler here, since the first overload matches the type exactly, whereas the second overload requires an extra decay-to-pointer step.
Now, I am able to get the above overload working by explicitly using type_traits as follows:
template <class T, std::size_t N>
void foo(const T (&arr)[N])
{
std::cout << "Array-reference overload!" << std::endl;
}
template <class T>
void foo(T ptr, typename std::enable_if<std::is_pointer<T>::value>::type* = 0)
{
std::cout << "Pointer overload!" << std::endl;
}
In this case, the program compiles and the overload that takes an array reference is selected. However, I don't understand why this solution should be necessary. I'd like to understand why the compiler considers a function that requires decay-to-pointer an equally likely overload candidate as the array reference, when the argument passed is very much an array.