20.4.  Namespaces

[ fromfile: namespaces.xml id: namespaces ]

In C and C++ there is one global scope that contains

Classes are one way of grouping names (members) under a common heading (the classname), but sometimes it is desirable to have a higher-level grouping of names.

The namespace mechanism provides a way to partition the global scope into individually named sub-scopes. This helps avoid naming conflicts that can arise when developing a program that uses modules with name conflicts. The syntax for defining a namespace is

        namespace namespaceName { decl1, decl2, ...}

Any legal identifier can be used for the optional namespaceName. Example 20.12 and Example 20.13 define two separate namespaces in different files, each containing functions with the same name.

Example 20.12. src/namespace/a.h

#include <iostream>
namespace A {
    using namespace std;
    void f() {
        cout << "f from A\n";
    }

    void g() {
        cout << "g from A\n";
    }
}

<include src="src/namespace/a.h" href="src/namespace/a.h" id="adoth" mode="cpp"/>


Example 20.13. src/namespace/b.h

#include <iostream>

namespace B {
    using namespace std;
    void f() {
        cout << "f from B\n";
    }

    void g() {
        cout << "g from B\n";
    }
}

<include src="src/namespace/b.h" href="src/namespace/b.h" id="bdoth" mode="cpp"/>


Example 20.14 includes both header files, and uses scope resolution to call functions declared in either file.

Example 20.14. src/namespace/namespace1.cc

#include "a.h"
#include "b.h"

int main() {
    A::f();
    B::g();
}
Output:

f from A
g from B


<include src="src/namespace/namespace1.cc" href="src/namespace/namespace1.cc" id="namespace1cc" mode="cpp"/>


The using keyword enables individual members of a namespace to be referenced without scope resolution. The syntax can take two forms.

  1. The using directive:

    using namespace namespaceName

    imports the entire namespace into the current scope.

  2. The using declaration:

    using namespaceName::identifier

    imports a particular identifier from that namespace into the current scope.

Care must be exercised to make sure that ambiguities are not produced when identifiers are present in more than one included namespace. We show an example of such an ambiguous function call in Example 20.15.

Example 20.15. src/namespace/namespace2.cc

#include "a.h"
#include "b.h"

int main() {
    using A::f;         1
    f();
    using namespace B;  2
    g();                3
    f();                4
}
Output:

f from A
g from B
f from A



1

Declaration - brings A::f() into scope.

2

Brings all of B into scope.

3

Okay.

4

Ambiguous!

<include src="src/namespace/namespace2.cc" href="src/namespace/namespace2.cc" id="namespace2cc" mode="cpp"/>


[Tip] namespace Aliases

To make sure that the names of various namespaces are unique, programmers sometimes need to produce extremely long namespace names. You can easily introduce an alias for a long namespace name with a command such as:

namespace xyz = verylongcomplicatednamespacename;