Я воспроизводству ниже аргумента-зависимого поиска (ADL) пример, приведенный на страницах 396 и 397 Страуструп книги (4-е издание):мне нужно некоторые разъяснения относительно этого примера на новой книге Страуструпа о ADL
namespace N {
struct S { int i; };
void f(S);
void g(S);
void h(int);
};
struct Base {
void f(N::S);
};
struct D : Base {
void mf(N::S);
void g(N::S x)
{
f(x); // call Base::f()
mf(x); // call D::mf()
h(1); // error: no h(int) available
}
};
Что приведенные выше комментарии правильны (я их протестировал), но это, похоже, не согласуется с тем, что автор говорит в следующем абзаце:
В стандарте правила для зависящего от аргумента поиска сформулированы в терминах связанных пространств имен (iso §3.4.2). В основном:
- Если аргумент является членом класса, ассоциированные пространства имен самого (в том числе его базовые классов) класс и вмещающих пространства имен класса.
- Если аргумент является членом пространства имен, связанные пространства имен являются охватывающими пространствами имен.
- Если аргумент является встроенным типом, не существует связанных пространств имен.
В примере, x
, который имеет тип N::S
не является членом класса D
, ни его основания Base
. Но это член namespace N
. Согласно второму этапу выше, функция N::f(S)
должна быть вызвана, а не Base::f()
.
Результат выше, также, кажется, не согласен со второй пулей в пункте 3.4.2p2 в стандарте, в котором говорится:
Если T является типом класса (включая профсоюзы), связанные с ним классы : сам класс; класс которого он является членом, если таковой имеется; и его прямых и косвенных базовых классов. Его ассоциированные пространства имен представляют собой пространства имен , членами которых являются ассоциированные классы. Кроме того, , если T является специализацией шаблона класса, его ассоциированные пространства имен и классы также включают: пространства имен и классы, связанные с типами аргументов шаблона, предоставленными для параметров шаблона (за исключением параметров шаблона шаблона); пространства имен, членами которых являются любые аргументы шаблона шаблона ; и классы, в которых используются любые шаблоны членов , используемые в качестве аргументов шаблона шаблона.
ADL срабатывает только в том случае, если функция не найдена с регулярным поиском. –
@ n.m неверно. Правило заключается в том, что ADL отключен, если обычный поиск находит локальное фактическое объявление функции (например, '{void f(); ..') или функция члена класса. Все остальные обычно найденные декларации (включая объявления локального использования) все еще позволяют ADL. –
@ н.м. Если это так, то в тот момент, когда вы выполнили 'operator <<' для своего класса в глобальном пространстве имен, вы больше не сможете писать 'std :: cout << std :: string (« Hello »);'. Этого, конечно, не бывает. –