Daily bit(e) C++. Поиск, зависящий от аргументов (ADL)
Daily bit(e) C++ #220, поиск при вызове неквалифицированной функции на основе аргументов: поиск, зависящий от аргументов (Argument Dependent Lookup, ADL).
Поиск, зависящий от аргументов, (ADL) определяет, как разрешаются вызовы неквалифицированных функций.
После поиска функции в текущем (и родительском) пространстве имен (упрощенно) также будут рассмотрены самые внутренние пространства имен типов аргументов.
Благодаря взаимодействию с правилами видимости мы можем настроить функции (вызываемые объекты) так, чтобы их можно было вызывать только через ADL или квалифицированные вызовы.
namespace lib1
{
struct X
{
friend void adl_only(const X&) {}
};
X operator+(const X&, const X&) { return {}; }
void operate(const X&) {}
void shut_off(const X&) {}
constexpr inline auto only_explicit = [](const X&) {};
}
constexpr inline auto shut_off = [](auto&&) {};
lib1::X a,b;
// Перегрузка оператора требует ADL.
a = a + b; // синтаксический сахар для: a = operator+(a, b);
// Без перегрузки оператора мы нам пришлось бы писать:
a = lib1::operator+(a, b);
// Вызов через ADL, поиск находит lib1::operate(),
// потому что decltype(a) == lib1::X
operate(a);
// Квалифицированный вызов всё еще работает.
lib1::operate(a);
// Нефункциональные сущности отключают ADL,
// это вызовет ::shut_off()
shut_off(a);
// Квалифицированный вызов всё еще работает.
lib1::shut_off(a);
// Дружественные функции являются членами окружающего
// пространства имен, но не видны за пределами ADL.
adl_only(a);
// lib1::adl_only(a); // Не скомпилируется, не видна за пределами ADL.
// Нефункциональные сущности также не участвуют в ADL.
// only_explicit(a); // Не скомпилируется, не видна ADL.
// Квалифицированный вызов всё еще работает.
lib1::only_explicit(a);
Открыть пример на Compiler Explorer.