Koenig lookup, named after Andrew Koenig, a former AT&T researcher and programmer known for his work with C++ is also known as argument dependent lookup.
Argument dependent lookup applies to the lookup of unqualified function through the namespaces according to the types of given arguments.
Let's go through a simple example.
#include <iostream> namespace NS1 { class A { public: A() {std::cout << "NS1::A::A";} }; template<typename T> void f(T a) { } } int main(int argc, char **argv) { NS1::A v; f(v); return 0; }Under normal conditions compiler will look for f in global namespace and fail as there is no such routine there. But modern compiler can be more intelligent: it can look at the arguments and exposes function from the namespace where arguments came. This will compile with modern compilers but will fail with old.
On the other hand the next piece of code might cause another kind problem.
#include <iostream> namespace NS1 { class A { public: A() {std::cout << "NS1::A::A";} }; template<typename T> void f(T a) { } } template<typename T> void f(T a) { } int main(int argc, char **argv) { NS1::A v; f(v); return 0; }The compilation will fail with compilers that do Koenig lookup with "call of overloaded function is ambiguous" error but will succeed with compilers that do not perform Koenig lookup. Old compilers will call function from the global namespace.
For portability the namespace should be declared explicitly.