Reputation: 8797
Suppose I have two overloads of a function
template <typename T>
void f(const T&) {
cout << "f(T&)" << endl;
}
template <typename T>
void f(const T*) {
cout << "f(T*)" << endl;
}
Why does f(new int)
resolves to the f(const T&)
instead of f(const T*)
? Anywhere in the standard talks about this counter-intuitive behavior?
Upvotes: 9
Views: 215
Reputation: 141628
For overload resolution with template deduction, the first step is to resolve the templates. Then non-template ordering is applied to the results. In your code the template resolutions are:
void f(int * const &) // 1
void f(int const *) // 2
According to C++14 [over.ics.ref], a reference binding directly to an argument as in (1) is an identity conversion (even if there are added cv-qualifiers). The binding of T
to T const &
is a direct binding, i.e. no temporaries are created and bound.
However, (2) involves a qualification conversion. The argument type int *
must be converted to const int *
before it matches the function parameter.
The identity conversion is considered a sub-sequence of any non-identity conversion sequence, so (1) wins according to the sub-sequence rule [over.ics.rank]/3.1.1
Upvotes: 13