Do You Prefer Explicit Namespaces or 'Using' in C++

Do you prefer explicit namespaces or 'using' in C++?

I always use using namespace for std & boost. Everything else I tend to use an explicit namespace unless it is used so much that it would clutter up the code.

In headers, I never use using namespace to avoid polluting the global namespace of the #including source.

Why is using namespace std; considered bad practice?

Consider two libraries called Foo and Bar:

using namespace foo;
using namespace bar;

Everything works fine, and you can call Blah() from Foo and Quux() from Bar without problems. But one day you upgrade to a new version of Foo 2.0, which now offers a function called Quux(). Now you've got a conflict: Both Foo 2.0 and Bar import Quux() into your global namespace. This is going to take some effort to fix, especially if the function parameters happen to match.

If you had used foo::Blah() and bar::Quux(), then the introduction of foo::Quux() would have been a non-event.

How do you properly use namespaces in C++?

Namespaces are packages essentially. They can be used like this:

namespace MyNamespace
{
class MyClass
{
};
}

Then in code:

MyNamespace::MyClass* pClass = new MyNamespace::MyClass();

Or, if you want to always use a specific namespace, you can do this:

using namespace MyNamespace;

MyClass* pClass = new MyClass();

Edit: Following what bernhardrusch has said, I tend not to use the "using namespace x" syntax at all, I usually explicitly specify the namespace when instantiating my objects (i.e. the first example I showed).

And as you asked below, you can use as many namespaces as you like.

C++ - Explicit & Implicit Namespace Implementation Differences

In general, there is no difference between the 2 versions you have shown, and you can use whichever one you prefer.

For what it's worth, here's one case where it differs slightly:

namespace A 
{
struct S{};
S f(); // declare f
}

and then:

namespace A 
{
S f() { return S{}; } // define f, ok
}

is fine, but the following is not:

S A::f() { return S{}; }

since S is used before the introduction of namespace A. This can be fixed by doing:

A::S A::f() { return S{}; }

or

auto A::f() -> S { return S{}; }

style and namespaces

Use std::cout to avoid any potential name clashes. If you use using using namespace std; you will populate your global namespace with all the std name which might conflict with classes or function names you or someone else in your team have written. This is well explained in the C++ faq lite and in SO

When to use :: for global scope in C++?

I use it quite infrequently; only when some ambiguity needs resolving for whatever reason. This is pretty subjective, though.

There may be some occasions (say, inside a template) where you're worried about ADL causing ambiguities only in certain cases:

template <typename T>
void foo(T t)
{
::bar(t); // :: just in case there's a `bar` in `T`'s namespace
}

Is it ok to qualify C functions with the `std` namespace?

If you use e.g. <math.h>

No, you shouldn't.

It is unspecified whether they are available in the namespace std on any particular implementation:

[C++11: D.5/2]: Every C header, each of which has a name of the form name.h, behaves as if each name placed in the standard library namespace by the corresponding cname header is placed within the global namespace scope. It is unspecified whether these names are first declared or defined within namespace scope (3.3.6) of the namespace std and are then injected into the global namespace scope by explicit using-declarations (7.3.3).

However, you should not be using this header:

[C++11: C.3.1/1]: For compatibility with the Standard C library, the C++ standard library provides the 18 C headers (D.5), but their use is deprecated in C++.


If you use e.g. <cmath>

Yes, you should.

It is unspecified whether they are available in the global namespace on any particular implementation:

[C++11: 17.6.1.2/4]: Except as noted in Clauses 18 through 30 and Annex D, the contents of each header cname shall be the same as that of the corresponding header name.h, as specified in the C standard library (1.2) or the C Unicode TR, as appropriate, as if by inclusion. In the C++ standard library, however, the declarations (except for names which are defined as macros in C) are within namespace scope (3.3.6) of the namespace std. It is unspecified whether these names are first declared within the global namespace scope and are then injected into namespace std by explicit using-declarations (7.3.3).

Should we be teaching beginners to use a global namespace?

I think the answer is "it doesn't really matter". It's a subtlety that's fairly easy to pick up and correct later.

Every beginners' programming text I know of makes a lot of simplifications and uses a lot of handwaving to hide a lot of what's going on ("this line is magic. Just type it in, and we'll discuss what it does later").

Beginners have enough to worry about without having to fully understand everything in their code, and how/why it is bad, so often these simplifications are good things.

Although in this case I kind of agree with you.

Adding the std:: prefix wouldn't be a big deal, and it would demystify namespaces quite a bit. using namespace std is actually much harder to explain and understand properly.

On the other hand, it takes up space and adds noise to the code which should be as concise and clear as possible.

C++ Namespace Noob Needs Assistance

These are practices that have served me well over many years. Hope you find this helpful.

1) Namespaces are an organizational technique for keeping like things together, usually for discoverability and to avoid name collisions with other code. They can be a great aid help when you're using intellisense-capable IDEs, making it easy to code without having to bounce back to docs to find something. Excessively fine-grained namespaces can be as detrimental to your code as no namespaces. While there's no hard rule here, but if you're consistently creating new namespaces for groups of less than 3-4 items, you are probably overdoing it. You also wouldn't typically define new namespaces inside a .cpp file, since that's the only file that would see it. I rarely see examples of the other extreme.

When working with templates, where everything is in headers, I like to create a "details" namespace under the main namespace to isolate the 'private' classes of the template library from the things that people are actually expected to use. There are other ways of achieving similar results that provide better encapsulation, but they are also more work to maintain.

2) Using statements should typically be isolated in C++ files, and not placed in headers, otherwise you lose track of what is 'used' pretty quickly in large projects. Similarly, it's best for portability and maintainability if your headers don't implicitly rely on using statements. You can make this easy to avoid by placing your using statements immediately after your include statements.

// main.cpp
#include "myheader1.h" // can't see using namespace std, ok.

using namespace std;

// Does this have std:: in front of everything that needs it?
// Maybe. Compiler won't tell me...
#include "myheader2.h"

Never put a using statement inside of an open namespace. That is, unless you really, really want to make peoples heads spin. This likely won't work like you (or the next guy) expects.

namespace A { ... }

namespace B {
using namespace A; // Don't do it!
}

In some cases, for absolutely ubiquitous namespaces, I see people put using statements in precompiled headers (is that just a VC++ thing?). I find that tolerable because they're usually local to a smaller body of code, though even there I think it's a stretch. It can facilitate the header dependency problem mentioned above.

3) That practice can get to be a nuisance, because you'll find that you have to keep going back for 'one more thing' and it can be confusing ("Wait, for this file did I use math::vector, physics::vector or std::vector?"). If you can't use the entire namespace because of collision issues, it may just be better to be explicit about at least one of the namespaces. If there's a lot of overlap, and maybe be explicit about both.

In some rare cases, with deeply nested namespaces, it may be useful to write something like this:

using namespace this::thing::is::ridiculous::someone::should::trim::it = ludicrous;

That allows to reference the namespace with a short moniker, e.g.

auto p = new ludicrous::SomeClass();

If you are going to do that, you should establish consistent conventions throughout the codebase for the namespaces that you do that to. If you use 3 different names in 3 different places, you just make the code less readable.



Related Topics



Leave a reply



Submit