Неконстантный указатель предпочитает const T& перегрузку const T*

Предположим, у меня есть две перегрузки функции

template <typename T>
void f(const T&) {
    cout << "f(T&)" << endl;
}

template <typename T>
void f(const T*) {
    cout << "f(T*)" << endl;
}

Почему f(new int) решает до f(const T&) вместо f(const T*)? Где-нибудь в стандарте говорится об этом нелогичном поведении?

http://ideone.com/kl8NxL

1 ответ

Решение

Для разрешения перегрузки с удержанием шаблона первым шагом является разрешение шаблонов. Затем к результатам применяется не шаблонное упорядочение. В вашем коде шаблонные разрешения:

void f(int * const &)   // 1

void f(int const *)     // 2

Согласно C++14 [over.ics.ref], привязка ссылки непосредственно к аргументу, как в (1), является преобразованием идентичности (даже если есть добавленные cv-квалификаторы). Привязка T в T const & является прямым связыванием, то есть никакие временные не создаются и не связаны.

Тем не менее, (2) включает преобразование квалификации. Тип аргумента int * должен быть преобразован в const int * прежде чем он соответствует параметру функции.

Преобразование идентичности считается подпоследовательностью любой последовательности преобразования неидентификации, поэтому (1) выигрывает в соответствии с правилом подпоследовательности [over.ics.rank]/3.1.1

Другие вопросы по тегам