cpp/language/adl

Argument-dependent lookup, also known as ADL, or Koenig lookup, is the set of rules for looking up the unqualified function names in , including implicit function calls to. These function names are looked up in the namespaces of their arguments in addition to the scopes and namespaces considered by the usual.

Details
First, the argument-dependent lookup is not considered if the lookup set produced by usual contains any of the following: @1@ a declaration of a class member @2@ a declaration of a function at block scope (that's not a ) @3@ any declaration that is not a function or a function template (e.g. a function object or another variable whose name conflicts with the name of the function that's being looked up)

Otherwise, for every argument in a function call expression its type is examined to determine the associated set of namespaces and classes that it will add to the lookup. @1@ For arguments of fundamental type, the associated set of namespaces and classes is empty. @2@ For arguments of class type (including union), the set consists of
 * @a@ The class itself
 * @b@ All of its direct and indirect base classes
 * @c@ If the class is a, the class of which it is a member
 * @d@ The innermost enclosing namespaces of the classes added to the set

@3@ For arguments whose type is a specialization, in addition to the class rules, the following types are examined and their associated classes and namespaces are added to the set
 * @a@ The types of all template arguments provided for type template parameters (skipping non-type template parameters and skipping template template parameters)
 * @b@ The namespaces in which any template template arguments are members
 * @c@ The classes in which any template template arguments are members (if they happen to be class member templates)

@4@ For arguments of enumeration type, the innermost enclosing namespace of the declaration of the enumeration type is defined is added to the set. If the enumeration type is a member of a class, that class is added to the set. @5@ For arguments of type pointer to T or pointer to an array of T, the type T is examined and its associated set of classes and namespaces is added to the set. @6@ For arguments of function type, the function parameter types and the function return type are examined and their associated set of classes and namespaces are added to the set. @7@ For arguments of type pointer to member function F of class X, the function parameter types, the function return type, and the class X are examined and their associated set of classes and namespaces are added to the set. @8@ For arguments of type pointer to data member T of class X, the member type and the type X are both examined and their associated set of classes and namespaces are added to the set. @9@ If the argument is the name or the (or function templates), every function in the overload set is examined and its associated set of classes and namespaces is added to the set.
 * Additionally, if the set of overloads is named by a, all of its type template arguments and template template arguments (but not non-type template arguments) are examined and their associated set of classes and namespaces are added to the set.

After the associated set of classes and namespaces is determined, all declarations found in classes of this set are discarded for the purpose of further ADL processing, except namespace-scoped friend functions and function templates, as stated in point 2 below.

The set of declarations found by ordinary and the set of declarations found in all elements of the associated set produced by ADL, are merged, with the following special rules @1@ in the associated namespaces are ignored @2@ namespace-scoped friend functions (and function templates) that are declared in an associated class are visible through ADL even if they are not visible through ordinary lookup @3@ all names except for the functions and function templates are ignored (no collision with variables)