Вы находитесь на странице: 1из 3

ADL относится главным образом к неквалифицированным именам, которые выглядят как

если бы они именовали функции, не являющиеся членами, в вызовах функций или


применениях операторов. ADL не будет выполняться, если обычный поиск находит:

* имя функции-члена;
* имя переменной;
* имя типа или
* имя объявления функции с областью видимости блока(1).

ADL также запрещен, если имя вызываемой функции заключено в круглые скобки.

(1) Поиск, зависящий от аргументов, не применяется, если обычный поиск имени


способен найти имя переменной, функции-члена, типа данных или имя объявления
функции с областью видимости в виде программного БЛОКА(см. пример кода).

В противном случае, если после имени следует заключенный в круглые скобки список
выражений аргументов, ADL выполняется путем поиска имени в пространствах имен и
классах, “связанных” или “ассоциированных” с типами аргументов вызова.

Если вы передаете в функции аргумент типа класса(в нашем случае это "x" типа A::X),
то при поиске имен(в нашем случае это имя функции) компилятор помимо прочих
рассматривает имена в пространстве имен содержащем тип аргумента. Работает только
при неквалифицированном поиске имен.

При поиске имени функции, указанного в выражении вызова функции, компилятор также
будет проверять пространства имен, содержащие типы аргументов вызова функции.

Точное определение множества связанных пространств имен и связанных классов для


данного типа регламентируется приведенными далее правилами:

* Для встроенных типов это пустое множество.


* Для типов указателей и массивов множество связанных пространств имени классов —
это пространства имен и классы лежащего в основе типа(на который указывает
указатель или который является типом элемента массива).
* Для перечислимых типов связанным пространством имен является пространство имен,
в котором объявлено перечисление.
* Для членов классов связанным классом является охватывающий класс.
* Для типов классов(включая объединения) множеством связанных классов является
сам тип класса, его охватывающий класс, а также все непосредственные или
опосредованные базовые классы. Множество связанных пространств имен представляет
собой пространства имен, в которых объявлены связанные классы. Если класс является
экземпляром шаблона класса, то сюда включаются и типы аргументов типов шаблона, а
также классы и пространства имен, в которых объявлены шаблонные аргументы шаблона.
* Для типов функций множества связанных пространств имен и классов включают
пространства имен и классы, связанные со всеми типами параметров, а также связанные
с типами возвращаемых значений.
* Для указателей на члены класса X множества связанных пространств имени классов
включают пространства имен и классы, связанные с X в дополнение к связанным с типом
члена класса (если это тип указателя на функцию-член, то учитываются также типы
параметров и возвращаемых значений этой функции-члена).

При применении ADL осуществляется последовательный поиск имени во всех связанных


пространствах имен так, как если бы это имя было квалифицировано поочередно с
помощью каждого из этих пространств имен(директивы using при этом игнорируются).

Например:

Для функций это правило работает только при их объявлении. Например:


#include <iostream>

namespace TestScope
{
struct TestStruct
{
int value;
};

void foo(TestStruct& ts) {std::cout << "2";}


}

void foo(TestScope::TestStruct& ts) {std::cout << "1";}

int main()
{
using ::foo;
TestScope::TestStruct ts;
foo(ts);
return 0;
}

OUT: ERROR!!!
In function 'int main()':
23:7: error: call of overloaded 'foo(TestScope::TestStruct&)' is ambiguous
23:7: note: candidates are:
16:6: note: void foo(TestScope::TestStruct&)
12:8: note: void TestScope::foo(TestScope::TestStruct&)

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

#include <iostream>

namespace TestScope
{
struct TestStruct
{
int value;
};

void foo( TestStruct& ts) {std::cout << "2";}

void foo( TestScope::TestStruct& ts) {std::cout << "1";}

int main()
{
void foo(TestScope::TestStruct& ts);
TestScope::TestStruct ts;
foo(ts);
return 0;
}

OUT: 1

Ссылки:
* https://habr.com/ru/company/jugru/blog/447900/
* https://ru.wikipedia.org/wiki/%D0%9F%D0%BE%D0%B8%D1%81%D0%BA,_
%D0%B7%D0%B0%D0%B2%D0%B8%D1%81%D1%8F%D1%89%D0%B8%D0%B9_%D0%BE%D1%82_
%D0%B0%D1%80%D0%B3%D1%83%D0%BC%D0%B5%D0%BD%D1%82%D0%BE%D0%B2

Вам также может понравиться