- Argument dependent name lookup
In the
C++ programming language , Koenig lookup, also known as argument dependent lookup (ADL), or argument dependent name lookup, applies to the lookup of an unqualified function name depending on the types of theargument s given to the function call. This behavior is named after Andrew Koenig.In Koenig lookup, other namespaces not considered during normal lookup may be searched. The set of namespaces to be searched depends on the types of the function arguments.
For a class A, there is a set of associated classes which make up its direct and indirect base classes. The set of associated namespaces for A is the namespace that contains A together with the namespaces containing A's associated classes. It is this set of associated namespaces that is searched for a function with an argument of type A.
If the normal lookup of the unqualified name finds a class member function, then Koenig lookup does not occur. Otherwise, the set of declarations found by lookup is the union of the declarations found by normal lookup with the declarations found by looking in the set of associated namespaces.
The
canonical example of Koenig lookup looks like this:A common pattern in theStandard Template Library is to declare overloaded operators that will be found in this manner. For example, this simpleHello World program would not compile if it weren't for Koenig lookup:Using<<
is equivalent to callingoperator<<
, which however lacks thestd
qualifier. In this case, functionstd::ostream& std::operator<<(std::ostream&, const char*)
is found through Koenig Lookup.Note that
is a function but it needs full qualification, since it is usedas an argument to
operator<<
(is a function pointer, not a function call).
Interfaces
Within C++, functions found by Koenig lookup are considered part of a class's interface. Within the
Standard Template Library , several algorithms make use of unqualified calls toswap
from within thestd
namespace. As a result, the genericfunction is used if nothing else is found, but if these algorithms are used with a third-party class,
Foo
, found in another namespace that also containsswap(Foo&, Foo&)
, that specialization ofswap
will be used.Criticism
While ADL makes it practical for free functions to be part of the interface of a class, it makes namespaces less strict and so can require the use of fully-qualified names when they would not otherwise be needed. For example, the C++ standard library makes extensive use of unqualified calls to to swap two values. The idea being that then one can define a specialization of std::swap in their own namespace and it will be used within the STL algorithms. In other words, the behavior ofmay or may not be the same as the behavior of(where
a
andb
are of typeN::A
) because ifN::swap(N::A&, N::A&)
exists, the second of the above examples call it while the first will not. Furthermore, if for some reason bothN::swap(N::A&, N::A&)
andstd::swap(N::A&, N::A&)
are defined, then the first example will callstd::swap(N::A&, N::A&)
but the second will not compile becauseswap(a, b)
would be ambiguous.In general, over-dependence on ADL can lead to semantic problems. If one library,
L1
, expects unqualified calls tofoo(T)
to have one meaning and another library,L2
expects it to have another, then namespaces lose their utility. If, however,L1
expectsL1::foo(T)
to have one meaning andL2
does likewise, then there is no conflict, but calls tofoo(T)
would have to be fully qualified (as opposed tousing L1::foo; foo(x);
) lest ADL get in the way.External links
* [http://www.gotw.ca/publications/mill02.htm "What's In a Class? - The Interface Principle"] by
Herb Sutter
* [http://www.gotw.ca/publications/mill08.htm "Namespaces and the Interface Principle"] byHerb Sutter
* [http://www.informit.com/guides/content.aspx?g=cplusplus&seqNum=286 Why I Hate Namespaces] by Danny Kalev
* [http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n2103.pdf "A Modest Proposal: Fixing ADL (revision 2)"] byHerb Sutter
Wikimedia Foundation. 2010.