Rules for binding an argument to a function to pass an array by reference or pointer to pass

To avoid confusion, I understand very well 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 accepts a reference to an array and another overload accepts 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 try to call the 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 the array reference will be selected by the compiler.

, GCC 4.9.2, , :

test.cpp:28:9: error: call of overloadedfoo(const char [2])’ is ambiguous

, , , .

, type_traits :

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;
}

, . , . , , decay-to-pointer , .

+6
1

, .

, , 1-.

$16.3.3.1.1 [over.ics.scs] 13 -

Conversion                   Category               Rank         Subclause
No conversions required      Identity               Exact Match
... ...
Array-to-pointer conversion  Lvalue Transformation  Exact Match  [conv.array]
... ...

, " " (.. 1- ) " ".

+4

All Articles