C++ Learning Note(5): Koenig Lookup

Development April 24th, 2007

This concept is well explained in the Wikipedia, and also in the codeproject. What confuses me is how this magic mentioned in Wikipedia is played:

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 std::swap to swap two values.

Here is my lousy approach to mimic the magic:

#include <iostream>
using namespace std;

void g();

void g() { cout << "g is outside NS" << endl; }

namespace NS {
        class A{};
        void f(A) { g(); cout << "f is called" << endl; }
        void g() { cout << "g is inside NS" << endl; }
}

int main()
{
        NS::A a;
        f(a);
}

with the following output:

g is outside NS
f is called

It looks good, suppose customized is missing, aka the Ln 6 is deleted. Compile, link, oops, gcc complains that the undefined reference to `g()’. Let’s move the g in the namespace before the f:

namespace NS {
        class A{};
        void g() { cout << "g is inside NS" << endl; }
        void f(A) { g(); cout << "f is called" << endl; }
}

It works, and the g inside NS namespace is called, no doubt, there is only g defined here. Let’s add a global g and check whether customized function is called, the full source code is:

#include <iostream>
using namespace std;

void g();

void g() { cout << "g is outside NS" << endl; }

namespace NS {
        class A{};
        void g() { cout << "g is inside NS" << endl; }
        void f(A) { g(); cout << "f is called" << endl; }
}

int main()
{
        NS::A a;
        f(a);
}

Wow, the output is:

g is inside NS
f is called

The global g is never called by NS::f! Is there something wrong? Please leave a feedback if you have an answer.