#include
template
';
}
template
';
}
int main()
{
int a = 5;
int * b = new int(7);
fun(a);
fun(b);
fun(const_cast
Ответ
Потому что для вызова функции с параметром-указателем компилятору надо выполнить квалификационное преобразование int * -> const int *
А для вызова функции с параметром-ссылкой компилятору надо выполнить привязку ссылки int *const & к указателю типа int *. Обратите внимание, что, в отличие от предыдущего варианта, в данном случае квалификатор const относится к указателю int * (!), а не к указуемому типу int
Оба варианта имеют статус exact match ("полное совпадение"), но в первом случае требуется навешивание дополнительного const на тип указуемого объекта, а во втором случае тип указуемого объекта совпадает точно. Поэтому вариант со ссылкой и выбирается в процессе overload resolution.
Можно убрать из рассмотрения шаблонность (она здесь только лишний туман создает) и сократить пример до такого
void foo(const int *p)
{
std::cout << " T*" << '
';
}
void foo(int *const &p)
{
std::cout << " T&" <<'
';
}
int main()
{
int *b = 0;
foo(b);
}
Здесь тоже будет вызваться ссылочная версия по тем же самым причинам.
Более того, и ссылочность тут тоже существенной роли не играет и ситуация в моем примере может быть сведена к выбору между
void foo(const int *p);
void foo(int *p);
В ситуации, когда можно вызвать функции с разными степенями cv-квалификации параметров, overload resolution выбирает наименее cv-квалифицированный вариант.
Комментариев нет:
Отправить комментарий