C++ namespaces advice

C++Namespaces

C++ Problem Overview


I'm just teaching myself C++ namespaces (coming from a C# background) and I'm really starting to think that even with all the things that C++ does better than most other languages, nested namespaces isn't one of them!

Am I right in thinking that in order to declare some nested namespaces I have to do the following:

namespace tier1
{
    namespace tier2
    {
        namespace tier3
        {
            /* then start your normal code nesting */
        }
    }
}

As opposed to:

namespace tier1::tier2::tier3
{
}

à la C#?

This becomes even more demented when I need to forward declare:

namespace tier1
{
    namespace tier2
    {
        namespace forward_declared_namespace
        {
            myType myVar; // forward declare
        }
        namespace tier3
        {
            /* then start your normal code nesting */
            class myClass
            {
                forward_declared_namespace::myType myMember;
            }
        }
    }
}

Bearing in mind that a typical system that I develop consists of:

MyCompany::MySolution::MyProject::System::[PossibleSections]::Type

Is this why you don't tend to see much use of namespaces in C++ examples? Or usually only single (not nested) namespaces?

UPDATE

For anyone interested, this is how I ended up tackling this issue.

C++ Solutions


Solution 1 - C++

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.

Solution 2 - C++

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.

Solution 3 - C++

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

Solution 4 - C++

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.

Solution 5 - C++

You can skip indentation. I often write

namespace myLib { namespace details {

/* source code */

} } /* myLib::details */

C++ source code is eventually compiled into binary, unlike C#/Java which stays in the binary. Therefore, namespace just provides a fine solution for variable naming conflict. It is not intended for class hierarchy.

I often keep one or two namespace levels in the code.

Solution 6 - C++

First of all you can avoid namespace indentation, because there is no reason for that.

Using namespaces in the examples won't show namespaces power. And their power as for me is dividing Domain areas one from another. Divide utility classes from the business ones.

Just don't mix different namespace hierarchies in the one .h file. Namespaces are kind of extra comment for your interface of functions declaration. Looking on namespaces and the class names should explain a lot of stuff.

namespace product
{
namespace DAO
{

class Entity
{
};

Solution 7 - C++

I have found that you can sort of mimic the c# namespace like this;

namespace ABC_Maths{
    class POINT2{};
    class Complex{};
}

namespace ABC_Maths_Conversion{
    ABC_MATHS::Complex ComplexFromPOINT2(ABC_MATHS::POINT2)
    {return new ABC_MATHS::Complex();}

    ABC_MATHS::POINT4 POINT2FromComplex(ABC_MATHS::COMPLEX)
    {return new ABC_MATHS::POINT2();}
}

namespace ABC
{
}

But code doesn't seem to be very tidy. and i would expect to have long winded usage

It is better to nest as much functionality into classes something like

namespace ABC{
    class Maths{
        public:
        class POINT2{};
        class Complex:POINT2{};
        class Conversion{
            public:
            static Maths.Complex ComplexFromPOINT2(MATHS.POINT2 p)
            {return new MATHS.Complex();}

            static MATHS.POINT2 POINT2FromComplex(MATHS.COMPLEX p)
            {return new ABC::MATHS.POINT2();}// Can reference via the namespace if needed
} /*end ABC namespace*/

And that is still a little bit long winded. but does feel a little bit OO.

And hears how it seems best done

namespace ABC
{
    class POINT2{};
    class Complex:POINT2{};
    Complex ComplexFromPOINT2(POINT2 p){return new Complex();}
    POINT2 POINT2FromComplex(Complex){return new POINT2();}
}

hears how usages would look

int main()
{
    ABC_Maths::Complex p = ABC_Maths_Conversion::ComplexFromPOINT2(new ABC_MATHS::POINT2());

    // or THE CLASS WAY

    ABC.Maths.Complex p = ABC.Maths.Conversion.ComplexFromPOINT2(new ABC.Maths.POINT2());

    // or if in/using the ABC namespace

    Maths.Complex p = Maths.Conversion.ComplexFromPOINT2(new Maths.POINT2());

    // and in the final case

    ABC::Complex p = ABC::ComplexFromPOINT2(new ABC::POINT2());
}

its been interesting to find out why i never used c++ namespaces like i would with c#. It would be too long winded, and would never work the same way as c# namespaces.

the best use for namespaces in c++ is to stop say my super cout function (that dings every time its called) from getting mixed up with the std::cout function (which is far less impressive).

Just because c# and c++ have namespaces, it doesn't mean that namespace means the same thing. they are different but similar. The idea for c# namespaces must have come from c++ namespaces. somebody must have seen what a similar but different thing could do, and didn't have enough imagination power left to give it its own original name like "ClassPath" which would kind of make more sense as its a path to classes rather than for providing naming spaces where each space can have the same names

I hope this helps someone

I forgot to say That all of these ways are valid, and moderate use of the first two can be incorporated into the the third to create a library that makes sense ie(not great example)

_INT::POINT2{}

and

_DOUBLE::POINT2{}

so you can change the precision level by using

#define PREC _DOUBLE 
// or #define PREC _INT 

and then creating an instance of PREC::POINT2 for double precision POINT2

That is not an easy thing to do with c# or java namespaces

obviously that's just one example. Think about how the usage read.

Solution 8 - C++

I sometimes declare deep namespaces as a couple of macros in a separate header

namespace.h

#define NAMESPACE_TIER1_TIER2_TIER3 \
    namespace tier1 { \
    namespace tier2 { \
    namespace tier3 {

#define END_NAMESPACE_TIER1_TIER2_TIER3 }}}

To use it somewhere else:

anotherfile.h

#include "./namespace.h"

NAMESPACE_TIER1_TIER2_TIER3;

/* Code here */

END_NAMESPACE_TIER1_TIER2_TIER3;

The redundant semicolons after the macro are to avoid extra indentation.

Solution 9 - C++

You're over-using them (and you'll get nothing in return).

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
QuestionAdam NaylorView Question on Stackoverflow
Solution 1 - C++anonView Answer on Stackoverflow
Solution 2 - C++Binary WorrierView Answer on Stackoverflow
Solution 3 - C++mipView Answer on Stackoverflow
Solution 4 - C++Bill LynchView Answer on Stackoverflow
Solution 5 - C++cuteCATView Answer on Stackoverflow
Solution 6 - C++Mykola GolubyevView Answer on Stackoverflow
Solution 7 - C++Ace_Of_JohnView Answer on Stackoverflow
Solution 8 - C++icecreamView Answer on Stackoverflow
Solution 9 - C++Jimmy JView Answer on Stackoverflow