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