6 Basic concepts [basic]

6.4 Name lookup [basic.lookup]

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

When the postfix-expression in a function call is an unqualified-id, other namespaces not considered during the usual unqualified lookup may be searched, and in those namespaces, namespace-scope friend function or function template declarations ([class.friend]) not otherwise visible may be found. These modifications to the search depend on the types of the arguments (and for template template arguments, the namespace of the template argument). [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]

For each argument type T in the function call, there is a set of zero or more associated namespaces and a set of zero or more associated classes to be considered. The sets of namespaces and classes are determined entirely by the types of the function arguments (and the namespace of any template template argument). Typedef names and using-declarations used to specify the types do not contribute to this set. The sets of namespaces and classes are determined in the following way:

If an associated namespace is an inline namespace, its enclosing namespace is also included in the set. If an associated namespace directly contains inline namespaces, those inline namespaces are also included in the set. In addition, if the argument is the name or address of a set of overloaded functions and/or function templates, its associated classes and namespaces are the union of those associated with each of the members of the set, i.e., the classes and namespaces associated with its parameter types and return type. Additionally, if the aforementioned set of overloaded functions is named with a template-id, its associated classes and namespaces also include those of its type template-arguments and its template template-arguments.

Let X be the lookup set produced by unqualified lookup and let Y be the lookup set produced by argument dependent lookup (defined as follows). If X contains

then Y is empty. Otherwise Y is the set of declarations found in the namespaces associated with the argument types as described below. The set of declarations found by the lookup of the name is the union of X and Y. [Note: The namespaces and classes associated with the argument types can include namespaces and classes already considered by the ordinary unqualified lookup. 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]

When considering an associated namespace, the lookup is the same as the lookup performed when the associated namespace is used as a qualifier ([namespace.qual]) except that: