117

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?

Mogsdad
  • 44,709
  • 21
  • 151
  • 275
nickolay
  • 3,643
  • 3
  • 32
  • 40
  • 39
    There's also option 3: Just us the full name, e.g. `int MyNamespace::MyClass::foo() ...`. – Benjamin Bannier May 30 '12 at 12:53
  • 1
    Possible duplicate: http://stackoverflow.com/questions/7789163/using-directive-best-practice – David May 30 '12 at 12:54
  • 1
    @Dave not duplicate. These questions complement each other. Recommend to add the link provided by Dave as "Read also..." to this question. My question will help novices to choose the correct style. – nickolay May 30 '12 at 13:06
  • Possible duplicate: http://stackoverflow.com/questions/8210935/creating-a-c-namespace-in-header-and-source-cpp – Firedragon Jul 17 '12 at 13:32

6 Answers6

86

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

Dan F
  • 17,654
  • 5
  • 72
  • 110
  • The question Dave linked in his comment to your question also outlines some key points in the differences (if any) between the two methods you're looking at – Dan F May 30 '12 at 13:02
  • 1
    Guys, I really do not know whose answer to select. They have intersection while complement each other. – nickolay May 31 '12 at 01:24
  • 1
    Just commenting to acknowledge that some IDE's like CLion will only detect implementations if you use option/practice #2. – pedrostanaka Jul 03 '15 at 00:40
  • @PedroTanaka is this still the case? I have not noticed any such problem. – John McFarlane Jun 01 '16 at 20:47
  • @JMcF I haven't checked since the time I published the comment. In early versions of Clion the problem occurred. – pedrostanaka Jun 04 '16 at 13:47
  • The option 3 presented below `int MyNamespace::MyClass::foo() {...}` is working correctly in CLion 2020.2.1 – pdaawr Sep 02 '20 at 16:30
64

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.

codeling
  • 11,056
  • 4
  • 42
  • 71
James Kanze
  • 150,581
  • 18
  • 184
  • 329
  • 2
    Guys, I really do not know whose answer to select. They have intersection while complement each other. – nickolay May 31 '12 at 01:24
12

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() { ... }
John McFarlane
  • 5,528
  • 4
  • 34
  • 38
7

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.

Jordan
  • 1,375
  • 14
  • 17
4

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.

codeling
  • 11,056
  • 4
  • 42
  • 71
Joanna
  • 153
  • 1
  • 6
1

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).

Konstantin Burlachenko
  • 5,233
  • 2
  • 41
  • 40