6 Basic concepts [basic]

6.4 Name lookup [basic.lookup]

6.4.2 Argument-dependent name lookup [basic.lookup.argdep]

Когда 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 noteExample:

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]).

  • Все имена, кроме (возможно, перегруженных) функций и шаблонов функций, игнорируются.