Когда postfix-expressionin a function call является an unqualified-id, unqualified lookup могут быть найдены другие пространства имен, не рассматриваемые в обычном режиме , и в этих пространствах имен могут быть найдены дружественные функции области пространства имен или объявления шаблонов функций ([class.friend]), которые иным образом не видны. Эти изменения в поиске зависят от типов аргументов (а для аргументов шаблона шаблона - пространства имен аргумента шаблона). [ Example:
namespace N { struct S { }; void f(S); } void g() { N::S s; f(s); // OK: calls N::f (f)(s); // error: N::f not considered; parentheses prevent argument-dependent lookup }
— end example ]
Для каждого типа аргумента T в вызове функции существует набор из нуля или более associated namespaces и набор из нуля или более, associated classes которые следует учитывать. Наборы пространств имен и классов полностью определяются типами аргументов функции (и пространством имен любого аргумента шаблона шаблона). Имена Typedef, using-declarations используемые для указания типов, не участвуют в этом наборе. Наборы пространств имен и классов определяются следующим образом:
Если T это фундаментальный тип, связанные с ним наборы пространств имен и классов пусты.
Если T это тип класса (включая объединения), то связанные с ним классы: сам класс; класс, членом которого он является, если таковой имеется; и его прямые и косвенные базовые классы. Связанные с ним пространства имен - это самые внутренние включающие пространства имен связанных с ним классов. Кроме того, если T это специализация шаблона класса, связанные с ней пространства имен и классы также включают: пространства имен и классы, связанные с типами аргументов шаблона, предоставленными для параметров типа шаблона (исключая параметры шаблона шаблона); пространства имен, членами которых являются любые аргументы шаблона шаблона; и классы, членами которых являются любые шаблоны-элементы, используемые в качестве аргументов шаблона шаблона. [ Note: Аргументы шаблона, не являющиеся типом, не влияют на набор связанных пространств имен. ] — end note
Если T это тип перечисления, связанное с ним пространство имен является самым внутренним охватывающим пространством имен его объявления. Если это член класса, связанный с ним класс - это класс члена; иначе у него нет ассоциированного класса.
Если T это указатель U или массив U, связанные с ним пространства имен и классы - это те, с которыми связаны U.
Если T это тип функции, связанные с ним пространства имен и классы - это те, которые связаны с типами параметров функции и те, которые связаны с типом возвращаемого значения.
Если T это указатель на функцию-член класса X, связанные с ним пространства имен и классы - это те, которые связаны с типами параметров функции и типом возвращаемого значения, вместе с теми, которые связаны с X.
Если T это указатель на член данных класса X, связанные с ним пространства имен и классы - это те, которые связаны с типом члена вместе с теми, которые связаны с X.
Если связанное пространство имен - это inline namespaceпространство имен, в которое оно входит, также включается в набор. Если связанное пространство имен непосредственно содержит встроенные пространства имен, эти встроенные пространства имен также включаются в набор. Кроме того, если аргумент является именем или адресом набора перегруженных функций и / или шаблонов функций, связанные с ним классы и пространства имен представляют собой объединение классов и пространств имен, связанных с каждым из членов набора, т. Е. Связанных классов и пространств имен. с типами параметров и возвращаемым типом. Кроме того, если вышеупомянутый набор перегруженных функций назван с template-id, связанные с ним классы и пространства имен также включают классы и пространства имен этого типа template-arguments и его шаблона template-arguments.
Пусть X будет набором поиска, созданным, unqualified lookup и пусть Y будет набором поиска, созданным поиском, зависимым от аргументов (определенным следующим образом). Если X содержит
объявление члена класса или
объявление функции блочной области, которое не является using-declaration, или
объявление, которое не является ни функцией, ни шаблоном функции
то Y пусто. В противном случае Y набор объявлений находится в пространствах имен, связанных с типами аргументов, как описано ниже. Набор объявлений, найденный при поиске имени, представляет собой объединение X и Y. [ Note: Пространства имен и классы, связанные с типами аргументов, могут включать пространства имен и классы, уже учтенные обычным неквалифицированным поиском. ] [ — end note Example:
namespace NS { class T { }; void f(T); void g(T, int); } NS::T parm; void g(NS::T, float); int main() { f(parm); // OK: calls NS::f extern void g(NS::T, float); g(parm, 1); // OK: calls g(NS::T, float) }
— end example ]
При рассмотрении связанного пространства имен поиск такой же, как поиск, выполняемый, когда связанное пространство имен используется в качестве квалификатора ([namespace.qual]), за исключением того, что:
Любые using-directives элементы в связанном пространстве имен игнорируются.
Любые дружественные функции в области видимости пространства имен или шаблоны дружественных функций, объявленные в связанных классах, видны в их соответствующих пространствах имен, даже если они не видны во время обычного поиска ([class.friend]).
Все имена, кроме (возможно, перегруженных) функций и шаблонов функций, игнорируются.