Jookia
Jookia

Reputation: 6880

C++ using Namespace In Source Files

Say I'm making a project and I have most the project in a namespace named Project. I define a class inside the namespace Project named MainProject.

In the source file, to implement the class, do I do 'using namespace Project;' or do I wrap it in a 'namespace Project { ... }' nest?

Upvotes: 6

Views: 4824

Answers (4)

Steve M
Steve M

Reputation: 8516

Given a header "n.h":

namespace n{
  extern void f();
}

The following does not define f() in namespace n (from here on, I'll refer to it as n::f:

#include "n.h"
using namespace n;

void f(){ }

If you try to refer to n::f anywhere, you'll get a link-time error. The above defines an f in the global namespace. This does define n::f:

#include "n.h"
void n::f(){ }

This also does:

#include "n.h"
namespace n{
  void f(){ }
}

but has a downside where if you mis-type the name or signature, you'll add a new function to the namespace and leave void n::f() undefined, leading to a semi-annoying link-time error.

When classes are involved, things are a little different:

namespace n{
  class c{
    void f();
  };
  extern c operator + (const c&, const c&); // I'll use Matthieu M.'s example
}

This will be okay, because there is no global c:

#include "n.h"
using namespace n;
void c::f(){ }

But the following will cause a link-time error if you try to add two c's, for the same reason as with the first attempt at defining n::f():

#include "n.h"
using namespace n;
c operator + (const c &a, const c &b){ /* blah blah */ } // define global +

This scenario will also cause a link-time error (or maybe even a compilation error, depending on where ::c::f is defined):

class c{ // a global c, defined in some header somewhere
  void f();
};

#include "n.h"
using namespace n;
void c::f(){ } // define the global c::f (a possible redefinition) and n::c::f remains undefined!

Upvotes: 9

Matthieu M.
Matthieu M.

Reputation: 299730

There are (subtle) issues with the using namespace xxx; syntax. Among which name clashes...

In general, it is thus better NOT to use it. I would recommend to re-open the namespace rather than prepending the identifiers with the namespace name but it is more a matter of taste.

Example of subtle issue:

// header
namespace foo
{
  struct Bar
  {
    explicit Bar(int i);
    int x;
  };
  Bar operator+(Bar lhs, Bar rhs);
}

// source
#include "the header here"

using namespace foo;

Bar operator+(Bar lhs, Bar rhs)
{
  return Bar(lhs.x + rhs.x);
}

which provokes a compilation error.

Upvotes: 1

Chubsdad
Chubsdad

Reputation: 25487

It is better to re-open the same namespace and then provide the implementation of the class rather than in a different (enclosing) namespace. This is primarily from modularity and it's related benefits perspective.

Upvotes: 2

Björn Pollex
Björn Pollex

Reputation: 76778

Both method are fine, it is really a matter of taste (or naming conflicts). I usually do neither and just prepend the namespace where necessary.

Upvotes: 3

Related Questions