Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ namespaces advice

Tags:

c++

namespaces

People also ask

How do you use namespaces correctly?

Typically, you declare a namespace in a header file. If your function implementations are in a separate file, then qualify the function names, as in this example. A namespace can be declared in multiple blocks in a single file, and in multiple files.

Should you use namespaces?

Under no circumstances must you use namespace std within a header file, that's a recipe for errors straight away. Do use namespaces, they will make your code so much more sorted out. And finally if you're going to use namespace STD, don't write functions that have the same name to functions within the standard library.

Why is using namespace a bad practice?

While this practice is okay for example code, pulling in the entire std namespace into the global namespace is not good as it defeats the purpose of namespaces and can lead to name collisions. This situation is called namespace pollution.

Should namespaces be indented?

LLVM Coding Standards, https://llvm.org/docs/CodingStandards.html#namespace-indentation: In general, we strive to reduce indentation wherever possible. [...] To facilitate this and avoid some insanely deep nesting on occasion, don't indent namespaces.


C++ namespaces were not intended to be a design mechanism - they are there simply to prevent name clashes. You really don't want or need to use nested namespaces in 99.99% of situations.

A good example of the correct use of namespaces in C++ is the C++ Standard Library. Everything in this quite large library is placed in a single namespace called std - there is no attempt or need to break the library up into (for example) an I/O sub-namespace, a math sub-namespace, a container sub-namespace etc.

The basic tool for modelling in C++ is the class (and to some extent the template), not the namespace. If you feel the need for nesting, you should consider using nested classes, which have the following advantages over namespaces:

  • they have methods
  • they can control access
  • they cannot be re-opened

Having considered these, if you still wish to use nested namespaces by all means do so - there is nothing technically wrong with using them in this way.


C++ namespaces were a vast improvement over the previous offering (i.e. no namespaces at all). C# namespaces have extended the concept and ran with it. I would advise you to keep your namespaces in a simple flat structure.

EDIT Do you advise that due to the short comings i've outlined here?

Simply "Yes". C++ namespaces weren't designed to help you partition your logic & libraries the way they do in C#.

The purpose of C++ namespaces is to stop the real world problem encountered by C developers, where they experience name collisions when using two third party libs that export the same function name(s). C developers had various workarounds for it, but it could be a serious pain.

The idea was that the STL etc has the std:: namespace, libs provided by "XYZ Corp" would have an xyz:: namespace, you working for "ABC corp" would put all your stuff in a single abc:: namespace.


what I do when forward declaring looks like this:

 namespace abc { namespace sub { namespace subsub { class MyClass; }}}

My forward declarations are collapsed into single line. Readability of forward declaration is sacrificed in return for the readability of the rest of code. And for definitions I don't use indentations either:

 namespace abc {
 namespace sub {
 namespace subsub {
 
 class MyClass 
 {
    public:
       MyClass();

       void normalIntendationsHere() const;
 };

 }
 }
 }

Using this style requires a bit of discipline at the beginning, but it's the best compromise for me.


Since C++17 you can declare namespace with a syntax proposed by the author of the question.

namespace A::B::C { ... }

nested namespace definition: namespace A::B::C { ... } is equivalent to namespace A { namespace B { namespace C { ... } } }.

https://en.cppreference.com/w/cpp/language/namespace


Atleast as a small help, in some cases you can do this:

namespace foo = A::B::C::D;

And then reference A::B::C::D as foo. But only in some cases.