C++: Namespaces -- How to use in header and source files correctly?

C++NamespacesHeader Files

C++ Problem Overview


Consider a pair of two source files: an interface declaration file (*.h or *.hpp) and its implementation file (*.cpp).

Let the *.h file be like the following:

namespace MyNamespace {
  class MyClass {
  public:
    int foo();
  };
}

I have seen two different practices for using namespaces in source files:

*.cpp showing practice #1:

#include "MyClass.h"
using namespace MyNamespace;

int MyClass::foo() { ... }

*.cpp showing practice #2:

#include "MyClass.h"
namespace MyNamespace {

  int MyClass::foo() { ... }

}

My question: Are there any differences between these two practices and is one considered better than the other?

C++ Solutions


Solution 1 - C++

From a code readability standpoint, it is probably better in my opinion to use the #2 method for this reason:

You can be using multiple namespaces at a time, and any object or function written below that line can belong to any of those namespaces (barring naming conflicts). Wrapping the whole file in a namespace block is more explicit, and allows you to declare new functions and variables that belong to that namespace within the .cpp file as well

Solution 2 - C++

The clearest is the option you didn't show:

int MyNamespace::MyClass::foo()
{
    //  ...
}

It's also very verbose; too much so for most people. Since using namespace is a recipe for name conflicts, at least in my experience, and should be avoided except in very limited scopes and places, I generally use your #2.

Solution 3 - C++

> Are there any differences between these two practices

Yes. #1 and #2 are examples of a using-directive and a namespace definition respectively. They are effectively the same in this case but have other consequences. For instance, if you introduce a new identifier alongside MyClass::foo, it will have a different scope:

#1:

using namespace MyNamespace;
int x;  // defines ::x

#2:

namespace MyNamespace {
  int x;  // defines MyNamespace::x
}

> is one considered better than the other?

#1 Pros: a little more terse; harder to accidentally introduce something into MyNamespace unwittingly. Cons: may pull in existing identifiers unintentionally.

#2 Pros: more clear that definitions of existing identifiers and declarations of new identifiers both belong to MyNamespace. Cons: easier to unintentionally introduce identifiers to MyNamespace.

A criticism of both #1 and #2 is that they are referring to an entire namespace when you probably only care about the definition of members of MyNamespace::MyClass. This is heavy-handed and it communicates the intent poorly.

A possible alternative to #1 is a using-declaration which includes only the identifier you're interested in:

#include "MyClass.h"
using MyNamespace::MyClass;

int MyClass::foo() { ... }

Solution 4 - C++

I'd like also to add that if you decide due to some reason to implement a template specialization in a cpp file and just rely on using namespace you will run into the following problem:

// .h file
namespace someNameSpace
{
  template<typename T>
    class Demo
    {
      void foo();
    };
}

// .cpp file
using namespace someNameSpace;

template<typename T>
void Demo<T>::foo(){}

// this will produce
// error: specialization of 'template<class T> void someNameSpace::Demo<T>::foo()' in different namespace [-fpermissive]
template<>
void Demo<int>::foo(){}

Otherwise if you apply #2 method this will be fine.

Solution 5 - C++

I'd like to add one more way, using a using-declaration:

#include "MyClass.h"
using MyNamespace::MyClass;

int MyClass::foo() { ... }

This saves you from typing the namespace name many times, if a class has many functions.

Solution 6 - C++

I think the practice #1 is not correct C++ code at all. This code snippet defines ::MyClass::foo symbol, where the real full qualified name is ::MyNamespace::MyClass::foo.

To learn about namespaces you can read section 7.3 of the draft let's say for standard http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3690.pdf

This concept is pretty old from 1998 or so, so you can use any standard or books of B.Stroustroup to learn about it.

In C++ language the namespace is a named scope. The namespace, as opposed to the class definition, is open to adding new functions to it.

The construction "using namespace NS;" in C++ is called as using-directive, and it can be used for several goals in my practice:

  1. You can use this directive in another namespace to combine(mix) names from a different namespace.
  2. In the context of the compilation unit it appends synonyms to all variables in namespace NS.

To define symbol, you can use two mechanisms - you can use the explicit qualification with all namespaces via operating in global namespace in C++ source file.

Or You can open namespace and add definitions to it (practice #2).

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionnickolayView Question on Stackoverflow
Solution 1 - C++Dan FView Answer on Stackoverflow
Solution 2 - C++James KanzeView Answer on Stackoverflow
Solution 3 - C++John McFarlaneView Answer on Stackoverflow
Solution 4 - C++JordanView Answer on Stackoverflow
Solution 5 - C++JoannaView Answer on Stackoverflow
Solution 6 - C++Konstantin BurlachenkoView Answer on Stackoverflow