Monday, July 18, 2005

Koenig look-up and namespaces

I was running through some of the posts on codeguru and then suddenly saw this name referenced in Andreas Masur's post - "Koenig Lookup". I had heard it for the first time since I started with C++ and to be specific namespaces. So, I though of starting a look-up for myself and find what it really was! This post would be an introduction to the concept which we frequently use knowingly and most of the times unknowingly. Here it goes:

Keonig look-up is an algorithm devised by Andrew Koenig. This algorithm is also sometimes known as Argument-dependent Lookup. These days, it is used in all the standard conforming compilers in C++ which handle cases as shown in the example code below:

namespace MyNamespace{
class A {};
void func(A);

MyNamespace::A a; // global object of MyNamespace::A class.

//main method.
int main(){
func(a); // OK - MyNamespace::func is called.

Neither a using-declaration nor a using-directive appears in code above. And yet, the compiler will do the needful and that is correctly identifying the unqualified name "func" as the function declared in namespace MyNamespace by applying the algorithm we are talking about. How does it work? The algorithm tells the compiler to look at not just the usual places such as local scope, but also the namespaces that contain the argument's type. Thus, in the following line of code, the compiler finds that the object a, which is the argument of the function func, belongs to the namespace MyNamespace. So, it looks at that namespace to locate the declaration of "func", "guessing" what we wish to do.

Without this, namespaces would be imposing an unacceptable burden on the programmer, who would have to repeatedly specify the fully qualified names, or instead, use numerous using-declarations. There is abundant debate on the topic of advantages and disadvantages of this algorithm but lets see this example to support this feature.

using std::cout; //using declaration
int main(){
cout<<"hello world!"; //OK, operator <<>

The using declaration puts std::cout into the scope of main(), thereby enabling us to use the non-qualified name "cout". However, the overloaded <<>

std::operator<<(cout, "hello world!");

Isn't it a pain-saving appreciable feature. It's interesting to find out about things that we usually do unknowingly. It add value to our knowledge. Cheers.

No comments: