Неконстантный указатель предпочитает 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*)
? Где-нибудь в стандарте говорится об этом нелогичном поведении?
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