7 Common reasons of using the namespaces in a C++ project.

Namespaces were introduced to the C++ Standard in 1995 and usually they are defined like this:

A namespace defines a new scope. They provide a way to avoid name collisions.

Although namespaces are used extensively in recent C++ code, most older code does not use this facility. 

After exploring the source code of many C++ projects, here are some common reasons of using the namespaces in these projects.

1- Avoid name collisions.

In this case their use are just useful for the compiler, no added value for the developer to make the code more readable and maintainable.

2- Modularize the code

Modern C++ libraries use extensively the namespaces to modularize their code base, and they use the  “Namespace-by-feature” approach. Namespace-by-feature uses namespaces to reflect the feature set. It places all items related to a single feature (and only that feature) into a single namespace. This results in namespaces with high cohesion and high modularity, and with minimal coupling between namespaces. Items that work closely together are placed next to each other.

Boost is the best example of grouping by feature, it contains thousands of namespaces, each one is used to group a specific feature.

3- Anonymous namespace.

Namespace with no name avoids making global static variable. The “anonymous” namespace you have created will only be accessible within the file you created it in.

4- workarround of the enum issue.

“Traditional” enums in C++ export their enumerators in the surrounding scope ,which can lead to name collisions, if two different enums in the same have scope define enumerators with the same name,

In a large project, you would not be guaranteed that two distinct enums don’t both called with the same name. This issue was resolved in C++11, using  enum class which will implicitly scope the enum values within the enum’s name.

Many years ago the trick of declaring an enum inside a namespace is used, for example instead of declaring an enum like this

enum status{
  status_ok,
  status_error
};

it’s declared inside an namespace:

namespace status{
       enum status{
         ok,
          error
  };
}

Many C++ projects use this trick, for example the Unreal Engine source code use widely this technique.

5- Hiding details by convention

For templated libraries where the code is implemented in header files, it’s interesting to find a way to inform the library user that he do not need to use directly some specific types because they concern only the implementation. In C# the “internal” keyword did the job, but in C++ there’s no way to hide public types to the library user.

A common idiom in modern C++, pioneered by the developers of the Boost libraries, is to separate symbols that form part of the implementation of your module (that is, don’t form part of the public API) but that have to be publicly available into a separate sub-namespace, by convention named detail.

For example in the boost::math documentation, it’s specified that:

Functions not intended for use by applications are in boost::math::detail.

And the inline namespaces provided by C++11 brings two other possibilities:

When an inline namespace is defined, a using directive is implicitly inserted into its enclosing namespace. While looking up a qualified name through the enclosing namespace, members of the inline namespace are brought in and found by the implicit using directive, even if that name is declared in the enclosing namespace.

For example, if you compile the following code with USE_INLINE_B defined, the output of the resulting executable is 1; otherwise, the output is 2.

namespace A {
#if USE_INLINE_B
   inline
#endif
   namespace B {
      int foo(bool) { return 1; }
   }
   int foo(int) { return 2; }
}

int main(void) {
   return A::foo(true);
}

Here are the two other possibilities of using the inline namespaces as explained in this document.

6-Using inline namespace definitions in explicit instantiation and specialization

You can explicitly instantiate or specialize each member of an inline namespace as if it were a member of its enclosing namespace. Name lookup for the primary template of an explicit instantiation or specialization in a namespace, for example M, considers the inline namespaces whose enclosing namespace set includes M. For example:

namespace L {
   inline namespace M {
       template <typename T> class C; 
   }

   template <typename T> void f(T) { /*...*/ };
}

struct X { /*...*/ };
namespace L {
  template<> class C<X> { /*...*/ };    //template specialization
}

int main()
{
  L::C<X> r;
  f(r);  // fine, L is an associated namespace of C
}

In this example, M is an inline namespace of its enclosing namespace L, class C is a member of inline namespace M, so L is an associated namespace of class C.

The following rules apply when you use inline namespace definitions in explicit instantiation and specialization:

  • An explicit instantiation must be in an enclosing namespace of the primary template if the template name is qualified; otherwise, it must be in the nearest enclosing namespace of the primary template or a namespace in the enclosing namespace set.
  • An explicit specialization declaration must first be declared in the namespace scope of the nearest enclosing namespace of the primary template, or a namespace in the enclosing namespace set. If the declaration is not a definition, it may be defined later in any enclosing namespace.

7-Using inline namespace definitions in library versioning

With inline namespace definitions, you can provide a common source interface for a library with several implementations, and a user of the library can choose one implementation to be associated with the common interface. The following example demonstrates the use of inline namespace in library versioning with explicit specialization.

//foo.h
#ifndef SOME_LIBRARY_FOO_H_
   #define SOME_LIBRARY_FOO_H_
   namespace SomeLibrary
   {
      #ifdef SOME_LIBRARY_USE_VERSION_2_
         inline namespace version_2 { }
      #else    
      	  inline namespace version_1 { }
      #endif
      namespace version_1 {
       	 template <typename T> int foo(T a) {return 1;}
      }     
      namespace version_2 {
       	 template <typename T> int foo(T a) {return 2;}
      }
   }  
#endif 

//myFooCaller.C 
#include <Foo.h>
#include <iostream>

struct MyIntWrapper { int x;}; 

//Specialize SomeLibrary::foo()
//Should specialize the correct version of foo()

namespace SomeLibrary {
	  template <> int foo(MyIntWrapper a) { return a.x;}
}

int main(void) {
	  using namespace SomeLibrary;
	  MyIntWrapper intWrap = { 4 };
	  std::cout << foo(intWrap) + foo(1.0) << std::endl;
}

If you compile this example with SOME_LIBRARY_USE_VERSION_2_ defined, the output of the resulting executable is 6; otherwise, the output is 5. If the function call, foo(intWrap), is qualified with one of the inline namespaces, then you need to ensure that the explicit specialization is effective.