Kan Li
Kan Li

Reputation: 8797

Non-const pointer prefers const T& overload to const T*

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?

http://ideone.com/kl8NxL

Upvotes: 9

Views: 215

Answers (1)

M.M
M.M

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

Related Questions