Это ADL (Argument Dependent Lookup) или Koenig Lookup (для разработчика функции).Назначение этой функции заключается в том, что во многих случаях одно и то же пространство имен будет содержать типы и функции, которые можно применять к этим типам, и все они соответствуют интерфейсу .Если бы ADL не был на месте, вам пришлось бы ввести идентификаторы в область действия с помощью объявлений using
, или вы должны были бы квалифицировать вызовы.
Это становится кошмаром, поскольку язык допускает перегрузки операторов.Рассмотрим следующий пример:
namespace n {
struct test {};
test operator+( test, test const & ); // implemented
};
int main() {
n::test a,b;
n::test c = a + b; //without ADL: c = n::operator+( a, b )
}
Хотя это может показаться неловкой ситуацией, учтите, что n
может быть пространством имен std
, test
может быть ostream
, а operator+
можетbe operator<<
:
int main( int argc, char** ) {
std::cout << "Hi there, there are " << argc << " arguments" << std::endl;
}
Без ADL вызовы operator<<
должны были бы быть явными, и, кроме того, вы должны знать, какой из них реализован как свободная функция по сравнению с методом.Знаете ли вы, что std::cout << "Hi"
вызывает свободную функцию, а std::cout << 5
вызывает функцию-член?Не многие это понимают, а если серьезно, то почти никому нет до этого дела.ADL скрывает это от вас.