C++ Namespaces

A namespace is a named block of code within which names have local scope, that is, they do not add to or clash with the enclosing or global scope. Namespaces delimit areas and allow for modularity.

You declare a namespace line this:

namespace <namespace> { ... }

What you type within the curly brackets has local scope and does not clash with its enclosing scope.

Scope resolution

You can refer to a same-named global variable within a namespace by prefixing it with "::". In the following code global variable x, not its local namesake, is used to initialize another. Alternatively, you can invoke an object in another namespace by prefixing its name with its namespace.

char x = 'x';
namespace scratch {
     char x = 'y';
     char global_x = ::x;
}
if(scratch::global_x == x) ...;

using Declarations in Namespaces

Last, you may import either a whole namespace into the current one by typing:

using <namespace>;

or just one name from a namespace:

using <namespace>::<name>;

Namespaces Are Open

A namespace is open; that is, you can add names to it from several separate namespace declarations. For example:

namespace A {
int f();
// now A has member f()
}
namespace A {
int g();
// now A has two members, f() and g()
     }

That way, the members of a namespace need not be placed contiguously in a single file. This can be important when converting older programs to use namespaces.

Koenig Lookup

Note: Koenig Lookup is sometimes called argument dependent lookup.

Overloaded functions may be called without qualifying the function name with the namespace. Using a process called Koenig lookup the C++ compiler examines the argument type and looks for overloaded functions in the namespace of the argument type.

The following example illustrates Koenig lookup. Consider the case of someone using graph classes that are supplied by two different graph libraries. Each library has its own namespace, inside of which is defined a graph class and a num_vertices() function.

namespace lib_jack {
  class graph { /* . . . */ };
  int num vertices(const graph&) { /* . . . */ }
}
namespace lib_jill {
  class graph { /* . . . */ };
  int num vertices(const graph&) { /* . . . */ }
}

Suppose the user wants to apply some generic graph algorithm, say boost::pail(), to both of these graph types.

int main() {
  lib_jack::graph g1;
  boost::pail(g1);

  lib_jill::graph g2;
  boost::pail(g2);
}

Inside of the boost::pail() there is a call to num_vertices(). The desired behavior in this situation is that if a graph from lib_jack is used, then lib_jack::num vertices() gets called, but if the graph from lib_jill is used, then lib_jill::num_vertices() gets called. Koenig lookup is the C++ language feature that provides this behavior. Provided the function call is not qualified with a namespace, the C++ compiler will search the namespace of the arguments to find the correct function to call.