Return to namespace (thing)

In [C++], each [struct]ure, [class], or [union] has its own namespace. Within that namespace, [member] names will not conflict with other classes. (This was not the case with very very early versions of [C], which is why a lot of structures in the C standard library have their members prefixed with the struct name.)

Also, the 3rd edition of [The C++ Programming Language] introduces the separate concept of namespace as a keyword in its own right, which allows the programmer to assign an [identifier] or group of identifiers to a namespace. This helps reduce [global namespace pollution] which the [linker] hates so much, especially when there is a [collision]. Namespaces use the same qualification syntax as [class]es , but the two are not interchangeable. Namespaces are simpler, in that they only do [encapsulation]. Stroustrup says1 they are better than classes when you need namespace encapsulation, but don't need type checking and object overhead provided by a class.

In C++ (post 1997), all of the libraries have their own namespaces. The standard library lives in [std]:: of course. The standard C libraries are also in the std:: namespace.

The [using] keyword allows you to alias an identifier into the current [scope]; otherwise the namespace must be qualified for each use. Single identifiers from a namespace can be imported this way, or the entire namespace can be imported. If imported namespaces have overlapping symbols, they must be resolved at [compile time], rather than link time, and thus symbol collision errors are caught sooner. The using keyword can clarify which namespace's function is used, if the results are not as desired. Note well that if you just import all the namespaces, you will be back where you started, with the compiler complaining about ambiguous duplicate functions.

Unlike classes, namespaces are "open". The same namespace can be mentioned in different places, adding symbols to it in each place.

Namespaces don't have to be named, just like [enum]s don't have to be named. The effect of an unnamed namespace is that the symbols in the namespace will not be exported out of this [compilation unit]. Global static has nearly the same effect in C, but is depreciated in C++ in favor of namespaces. Global statics are mostly to prevent name collisions between modules--and namespaces do this better.

Stroustrup2 also recommends giving namespaces [American Telephone and Telegraph|long names] that include version numbers and full library names, and then using the namespace aliasing mechanism to alias back to a [AT&T|short name] that is more manageable. This way, you can [upgrade|change] which library you are using just by changing the namespace alias.

If a function is not found in the current namespace (and hasn't been [import]ed from another namespace), the compiler will search the namespaces of the argument types to that function in hopes of finding a matching prototype. Like many other resolution issues, this could seem [The C++ Programming Language Freakshow|magical].

For complex examples, check out a book. These examples should be enough to help figure out syntax, though.

namespace MyStuff {
int f();
}     // look, ma, no [When to use a semicolon in Pascal|semicolon]

namespace m=MyStuff;    // namespace alias

void g() { m::f(); }     // must be qualified

namespace MyStuff {    // extend it; must use original name, not alias.
int ff();
}

using m::f;    // import f into current namespace

void h() { f(); }    // qualification no longer needed

int MyStuff::f()    // define the function in the namespace
{
return ff();    // this doesn't need qualification to use m::ff
}

using namespace m;    // drag in the rest of MyStuff too

void k() { ff(); }

Note that MyStuff could have been used in place of m above except (obviously) in the alias statement. The alias name can't be used to add to the namespace, so m could not be used there.

Stroustrup hints that it might be a good idea to put everything except [main()] into appropriate namespaces. Certainly this would make resolving unintentional symbol collisions a lot easier at link time.

For more examples, see [using].

 

Sources:

  • 1 [Bjarne Stroustrup]: [The C++ Programming Language], 3rd edition, section 8.2.7
  • 2 [ibid]. appendix C.10.3
  • Rigorous testing of many flawed examples using [gnu] [g++]
Existing:


Non-Existing: