Koenig Lookup/ Argument -Dependent Lookup
lets suppose the following scenario -->
//Trivial namespace for testing purpose
namespace test
{
class A { }; //Empty Class
void f(int x) { cout<<x; } //simply ouputs the integer value passd
int f(A obj) { cout<<"OBJECT"; } //Prints OBJECT and takes an object of class A
}
int main()
{
//Inside main() i make a simple function call
f(10);
}
Now what will happen is that the compiler will search the global/free functions for
similar signature, but wont find one because there aint one. The function
void f(int x) is the namespace test and is inaccesible there until we use
using namespace test;
Now if i add a function
int f(int x)
{ cout<<x; }
int main()
{
//Inside main() i make a simple function call
f(10);
}
just before main() i.e in the global region, then the compiler will find a match when
called through main(). This is all so simple and obvious, isnt it?
Now a similar case -->
//Trivial namespace for testing purpose
namespace test
{
class A { }; //Empty Class
void f(int x) { cout<<x; } //simply ouputs the integer value passd
int f(A obj) { cout<<"OBJECT"; } //Prints OBJECT and takes an object of class A
}
int f(test::A obj) { cout<<"ANOTHER OBJECT"; } //Similar to function inside namespace
//but this one is just in global scope
int main()
{
//Inside main() i make a simple function call
test::A obj;
f(obj);
}
Now what will happen in this case. the obvious answer would be that global f() would be
called and ANOTHER OBJECT will be printed. but heres the truth guyz, the compiler will
deflect slightly from usual name-lookup and will use another kind of name-lookup because
the parameter you passed to the function is an object of a class/structure.
This kind of name-lookup is called KOENIG LOOKUP/ARGUMENT DEPENDENT LOOKUP.
and it would lead to an ambiguous call, the compiler would get confused between
test::f(A obj) and global int f(test::A obj)
although theres no using directive used.
The compiler will follow this rule --->
"If the parameter passed to a function is an object of a class/structure then the compiler
would also include those namespaces in which that class/structure or its object is
defined."
Well you would be thinking that whats the use of namespaces then, the namespaces are
still functional and continue to serve their purpose, but this is just one rare case in which
the compiler crosses the namespace boundary.
This kind of lookup called KOENIG LOOKUP was named after Andrew Koenig who nailed
its proper definition.