79

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.

Orvid King
  • 1,188
  • 10
  • 16
Adam Naylor
  • 6,172
  • 10
  • 49
  • 69

9 Answers9

117

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.

  • 19
    templates were not intended to be a mpl mechanism. But Guys use them in that way. – Mykola Golubyev Apr 03 '09 at 12:35
  • Good advice as always mr. butterworth! – Adam Naylor Apr 03 '09 at 12:37
  • Is it a good to name classes like DAOUser DAOPacient VIEWUser MODELUser, etc. – Mykola Golubyev Apr 03 '09 at 12:40
  • 14
    Eh . . . I hate to be a pedant (we all know that's a lie), but doesn't implement an ios namespace inside the std namespace? I don't have a C++ compiler handy at the moment . . . – Binary Worrier Apr 03 '09 at 13:16
  • 1
    Could you provide arguments (not examples), why is not good idea use nested namesapces? – bayda Apr 03 '09 at 13:19
  • @bb I believe in examples - they usually are the result of real world experience –  Apr 03 '09 at 13:26
  • 4
    @binary ios is a typedef for basic_ios –  Apr 03 '09 at 13:30
  • @Neil - I saw more examples without namespaces, with just one namespace, with nested namespace. I can't chose right way only by examples.. I need to see all pros and cons. – bayda Apr 03 '09 at 13:55
  • look at the boost at least. It is a library. And in the project there is can be library and the math module and ORM module and RPC module and other modules with the Data related to those parts. – Mykola Golubyev Apr 03 '09 at 13:56
  • @bb if I were to make one argument against it is that the world is not made up of things that split naturally into nested categories - hence the many failures of Linneaen taxonomy. Software isn't made that way either, IMHO. –  Apr 03 '09 at 13:59
  • @mykola - why didn't you make that point in your answer to the question? –  Apr 03 '09 at 14:04
  • @Neil: I don't know. I fill in the way that namespaces are design instrument. It is hard explain how you do breath when you breath every moment. – Mykola Golubyev Apr 04 '09 at 01:45
  • "you should consider using nested classes" and beside all those pros you mentioned they have one con - the nesting, which is I suppose essence of this question, will look EXACTLY like in Naylor's example... – mip Nov 21 '09 at 16:04
  • C++ has a `rel_ops` namespace in `std`, and C++0x adds a few others. – Johannes Schaub - litb Nov 21 '09 at 16:05
  • 7
    Namespaces in C++ have specific features in order to support interfaces in a more modular way. Please refer to the following rules in the excellent book "C++ Coding Standards" by Herb Sutter and Andrei Alexandrescu: 57: Keep a type and its nonmember function interface in the same namespace. 58: Keep types and functions in separate namespaces unless they’re specifically intended to work together. – alexk7 Jun 30 '10 at 19:36
  • 2
    Nested classes would be even worse in terms of the ability to forward-declare: you can't. Suppose you need to forward declare a nested type in order to put it into a standard container or smart pointer. If it is nested inside a class, you simply cannot do that. I learned this lesson from years of C++. Anything you need forward-declare must be at the namespace level, not nested inside a class. – rwong Jun 27 '16 at 14:25
  • 1
    If the source is readable and does what is intended, commented where needed with a concise explanation then it's my opinion that there are almost no limits on what you can achieve. Suppose someone had a global namespace with up to 25 depths of nested namespaces and the designer knows what defined types, macros, routines-methods-functions, class declarations, templates, const static global types, etc. and where they all belong and they are able to compile without warning or error then there really is nothing wrong and nothing in stopping them, however simplicity is more often looked for. – Francis Cugler Feb 09 '17 at 03:11
  • As a note, C++ officially _does_ in fact use namespaces for partitioning in some cases, although it's usually unnecessary because headers (and Modules, as of C++2a) handle the partitioning for you. Even then, it's still primarily used to prevent name collisions and unexpected behaviour, typically to prevent the addition of new features from breaking existing code. A good example of this would be the containers that use a `memory_resource`, which are in `std::pmr` so they don't interfere with the legacy versions in `std`. – Justin Time - Reinstate Monica Sep 21 '19 at 23:00
24

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.

Binary Worrier
  • 50,774
  • 20
  • 136
  • 184
  • 2
    Do you advise that due to the short comings i've outlined here? – Adam Naylor Apr 03 '09 at 12:29
  • 1
    If many people work at "ABC corp" for many projects there, and over the years, projects merge or get split up, it makes a lot of sense to have at least `abc::PROJECT` sub-namespaces. And if larger projects have clear sections, then `abc::PROJECT::SECTION` also makes sense. Even the C++ Gods have understood, that there are sections, and created sub-namespaces like `std::chrono` or `std::ios`. – Kai Petzke Sep 20 '20 at 11:13
20

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

mip
  • 8,355
  • 6
  • 53
  • 72
8

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.

Bill Lynch
  • 80,138
  • 16
  • 128
  • 173
6

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.

yairchu
  • 23,680
  • 7
  • 69
  • 109
cuteCAT
  • 2,251
  • 4
  • 25
  • 30
4

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
{
};
Mykola Golubyev
  • 57,943
  • 15
  • 89
  • 102
  • 3
    "First of all you can avoid namespace indentation, because there is no reason for that." that's exactly what i actually do ;) – Adam Naylor Apr 03 '09 at 12:30
  • Great point, and I think namespace power is further amplified when using [CASE](http://en.wikipedia.org/wiki/Computer-aided_software_engineering) tools to visualize code base relationships and layers. Tools like [CppDepend](http://www.cppdepend.com/) or Visual Studio's [Dependency Graph](http://msdn.microsoft.com/en-us/library/dd409453.aspx) take such developer built "code comprehensibility grips" that are structured via all the namespace nestings to really illuminate the layers and dependencies in a well structured coherent manner. – jxramos Dec 16 '14 at 20:24
0

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.

-2

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.

icecream
  • 973
  • 2
  • 12
  • 26
  • 3
    that's really messy and you'd have to define it for every nested namespace. plus, if you're going to write out `NAMESPACE_TIER1_TIER2_TIER3` and `END_NAMESPACE_TEIR1_TIER2_TIER3`, why not just write `namespace tier1{namespace tier2{namespace tier3{` and `}}}`? Altogether it's actually shorter. – Michael Dorst Jul 05 '12 at 22:07
  • I disagree, it's not shorter, and it creates a very deep indentation problem. I have tried both and and I prefer the #define method. Edit: ok, minus the indentation problem... – icecream Jul 06 '12 at 08:59
  • 2
    Prefer what you like, but I wouldn't recommend that to other users. It's not shorter (as you can see from my comment where the two are lined up) and that's not counting the definition, and it's certainly more difficult to track errors that way. What if you make a typo? The compiler won't know what's wrong and your error will show up in completely the wrong place. – Michael Dorst Jul 06 '12 at 16:15
  • 3
    The "shorter" argument doesn't really hold since it is dependent on the way the macros are defined. And about the "typo" argument. Write the wrong namespace name and you will get as cryptic messages as with the macro solution, but with the macro solution many modern IDE's can resolve that the name has not been defined and help you locate the error. The namespace name is just free text and you can write anything you want there, so it is actually harder to avoid typo problems when not using the macro. And there is no harm in "recommending" the macro solution, people can decide for themselves. – icecream Jul 09 '12 at 05:38
-2

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

Jimmy J
  • 1,953
  • 1
  • 14
  • 20
  • 15
    A hierarchical, ordered structure. (re “you’ll get nothing in return”) I think this is huge, and vastly underrated in C++. Just think of how this impacts on documentation. – Konrad Rudolph Nov 14 '09 at 11:34
  • 1
    @Konrad, i believe this is the essence of my question. – Adam Naylor Feb 26 '11 at 11:54
  • Question is very old, but it's still relevant to me today. I had same opinion as @KonradRudolph, but then I found out that ***nested*** namespaces are [worthless](http://open-std.org/JTC1/SC22/WG21/docs/papers/2017/p0816r0.pdf). The best way is to just have flat wide library namespace... It's sad, but it's best we've got right now. And this follows with the way std is structured. And it's structured this way for a reason - there's currently no better way. –  Dec 04 '19 at 17:22
  • @Sahsahae They’re definitely not worthless, not even in the opinion (!) of one senior member of the C++ standards committee. But even then, it’s only that: an opinion (which I do not share). I definitely don’t recommend nesting frivolously — but judicious use of nested namespaces is used widely and successfully in other languages, and doesn’t exhibit the defects that Titus posits. – Konrad Rudolph Dec 04 '19 at 17:33
  • @KonradRudolph Here's your issue: ***other*** languages. This question was strictly about C++ namespaces, and I haven't extended the scope of it. Funnily enough, just like C++ namespaces, I accidentally somehow managed to now extend it to "namespacing in all languages", because `langs::cpp` can still see everything in `langs`, with no real isolation to just `cpp`... This is exactly the issue with C++ namespacing and why flat structure is suggested. in Rust modules, for example, you couldn't access `langs::*` from `cpp`, and I never said that this is bad, it's great, but in C++ it's not that. –  Dec 04 '19 at 17:42
  • @Sahsahae While C++ namespaces do have unique issues, these are not deal-breakers, and the benefits demonstrated by other languages *still exist*. – Konrad Rudolph Dec 04 '19 at 17:46
  • They don't. If you believe that it's not the case, I'd suggest arguing with whoever wrote that paper, and I'd really suggest reading it at least a few times, it's short enough. There's close to none benefits and all downsides, in the long run you just end up typing more while your code breaks just the same way as if you just had flat structure, except flat structure would help to see the issue faster. –  Dec 04 '19 at 17:48