Почему static_pointer_cast не работает с ADL, но требует явного std::`?
Рассмотреть возможность
// https://godbolt.org/z/z5M9b9jzx
#include <memory>
#include <cassert>
struct B {};
struct D : B {};
int main() {
std::shared_ptr<B> b = std::make_shared<D>();
auto d = static_pointer_cast<D>(b);
assert(d);
}
Я ожидал неквалифицированного звонка
static_pointer_cast
разрешить
std::static_pointer_cast
, так как
b
, быть
std::shared_ptr
, должны принести
namespace std
в использовании ADL.
Почему нет? Мне нужно написать
std::shared_pointer_cast
явно, чтобы заставить его работать.
2 ответа
Если вы не используете C++20 , правила поиска не позволят этого.
Согласно определению ADL, чтобы он работал, выражение, обозначающее функцию, должно быть неквалифицированным идентификатором (это нормативный термин). И пока
Вызов функции (и ADL) не вступает в игру до тех пор, пока не будет определено постфиксное выражение.
По сути, нам нужно в первую очередь найти определение шаблона, чтобы его можно было проверить как действительное (аргументы шаблона могут быть переданы только шаблонам). Поскольку нет механизма, позволяющего нам находить
https://en.cppreference.com/w/cpp/language/adl
Хотя вызов функции может быть разрешен через ADL, даже если обычный поиск ничего не находит, для вызова функции шаблона функции с явно указанными аргументами шаблона требуется, чтобы было объявление шаблона, найденного обычным поиском (в противном случае это синтаксическая ошибка. встретить неизвестное имя, за которым следует символ «меньше»)(до C++20)
В режиме C++20 ваш код компилируется нормально, демонстрация: https://gcc.godbolt.org/z/b13q4hs68