129

I switched from C++ to Java and C# and think the usage of namespaces/packages is much better there (well structured). Then I came back to C++ and tried to use namespaces the same way but the required syntax is horrible within the header file.

namespace MyCompany
{
    namespace MyModule
    {
        namespace MyModulePart //e.g. Input
        {
            namespace MySubModulePart
            {
                namespace ...
                {
                    public class MyClass    

The following seems strange to me too (to avoid the deep indent):

namespace MyCompany
{
namespace MyModule
{
namespace MyModulePart //e.g. Input
{
namespace MySubModulePart
{
namespace ...
{
     public class MyClass
     {

Is there a shorter Way to express the above thing? I am missing something like

namespace MyCompany::MyModule::MyModulePart::...
{
   public class MyClass

Update

Ok, some say the concept of usage in Java/C# and C++ is different. Really? I think (dynamic) class loading is not the only purpose for namespaces (this is a very technical reasoned perspective). Why shouldn't I use it for a readability and structurization, e.g think of "IntelliSense".

Currently, there is no logic / glue between a namespace and what you can find there. Java and C# does this much better... Why including <iostream> and having namespace std? Ok, if you say the logic should rely on the header to include, why does the #include does not uses an "IntelliSense" friendly syntax like #include <std::io::stream> or <std/io/stream>? I think the missing structurization in the default libs is one weakness of C++ compared to Java/C#.

If uniqueness to avid conflicts is one Point (which is a point of C# and Java, too) a good idea is to use the project name or company name as namespace, don't you think so?

On the one hand it's said C++ is the most flexible... but everyone said "don't do this"? It seems to me C++ can do many things but has a horrible syntax even for the easiest things in many cases compared to C#.

Update 2

Most users say it is nonsense to create a deeper nesting than two Levels. Ok, so what about Windows::UI::Xaml and Windows::UI::Xaml::Controls::Primitives namespaces in Win8 development? I think Microsoft's usage of namespaces makes sense and it is indeed deeper than just 2 Levels. I think bigger libraries / projects need a deeper nesting (I hate class names like ExtraLongClassNameBecauseEveryThingIsInTheSameNameSpace... then you could put everything into the global namespace, too.)

Update 3 - Conclusion

Most say "don't do it", but... even boost has a deeper nesting then one or two levels. Yes, it is a library but: If you want reusable code - treat your own code like a library you would give someone else. I also use a deeper nesting for discovery purposes using namespaces.

Craig McQueen
  • 41,871
  • 30
  • 130
  • 181
Beachwalker
  • 7,685
  • 6
  • 52
  • 94
  • 3
    Is it an abuse of `namespace` keyword? – Nawaz Jul 06 '12 at 08:20
  • 4
    namespaces and c#/java module systems do not serve the same purpose, as such you should not try to use them the same way. and no, there is no simpler syntax, simply beacuse it makes no sense to provide a syntax to make things easier to do, that are not meant to do. – PlasmaHH Jul 06 '12 at 08:22
  • @PlasmaHH ... so the weakness is the missing structurization of the std lib of C++? (see my simple example within the update) – Beachwalker Jul 09 '12 at 09:01
  • @Stegi: If you can give sound arguments why it is missing, and what solid benefits we would get from such a structurization, we could talk about potential weaknesses. Until then I would call javas endless nesting of packages confusing at best. – PlasmaHH Jul 09 '12 at 09:50
  • 3
    @PlasmaHH Intellisense and other helpers for/after header (package)inclusion. Large Projects within one company might need more than one nesting (e.g. vw::golflib::io) for a clear statement what a namespace contains at which "scope". Well, you could just use vw:: but if namespace meant to be used to avoid clashes, why are the so horrible to declare? This ends up to a point that noone uses it or just uses namespace with a deepness of one (as often suggestet). – Beachwalker Jul 09 '12 at 14:10
  • @Stegi: intellisense is a nonsense argument, if it is too broken to cope with importing by header names, then you should fix it, not change the language to make it work better. my autocompletion works perfectly fine without endlessly nested namespaces. Nesting namespaces opens up exponentially much namespaces. If you need to nest your namespaces 5 levels deep because you have 32 classes that are all having the same name, then you are doing something really wrong. namespaces are not a replacement for grouping in your documentation. – PlasmaHH Jul 09 '12 at 14:18
  • "Yes, it is a library, but" I find it most interesting that everyone says "don't do this" without even considering the case that you might write a library yourself. You don't state anywhere that you don't write a library, so I think that a good answer should reflect this possibility. – Kaiserludi Aug 16 '18 at 16:07
  • 1
    Thank you for asking this question, I also feel that C++ really lacks a feature like this! – alexpanter Oct 22 '18 at 07:05

11 Answers11

178

C++17 might simplify nested namespace definition:

namespace A::B::C {
}

is equivalent to

namespace A { namespace B { namespace C {
} } }

See (8) on namespace page on cppreference:
http://en.cppreference.com/w/cpp/language/namespace

oHo
  • 51,447
  • 27
  • 165
  • 200
W1M0R
  • 3,367
  • 3
  • 30
  • 32
  • 7
    ... enabled by compiler switch `/std:c++latest ` – sunny moon Aug 10 '16 at 06:34
  • 4
    Note, that if you will use `/std:c++latest` in Visual Studio 2015 and also use Boost, you may encounter very mystical compiler errors when you include some Boost headers. I faced this problem as described [in this StackOverflow question](http://stackoverflow.com/questions/40108603/c2143-syntax-error-when-including-boost-optional-hpp) – Software Craftsman Oct 19 '16 at 08:06
  • 1
    It works as is, namespace A::B::C. I have tested with g++-6.0 – ervinbosenbacher Mar 12 '17 at 22:10
  • Though not accepted for the anonymous/unnamed namespace (not checked in the standard, but all major compiler suites [reject](https://godbolt.org/z/a4PKMo7T4) it) – here we still rely on a separate namespace declaration, but at least the surrounding ones can be condensed ;) – Aconcagua Sep 19 '22 at 15:23
33

To avoid really deep indenting, I usually do it this way:

namespace A { namespace B { namespace C
{
    class X
    {
        // ...
    };
}}}
Kurt Hutchinson
  • 2,959
  • 23
  • 30
  • 3
    JFYI `clang-format` cannot format that as you showing http://clang.llvm.org/docs/ClangFormatStyleOptions.html (NamespaceIndentation) – KindDragon Sep 06 '16 at 18:48
17

I fully support peterchen's answer but want to add something that addresses another part of your question.

Declaring namespaces is one of the very rare cases in C++ where I actually like the use of #defines.

#define MY_COMPANY_BEGIN  namespace MyCompany { // begin of the MyCompany namespace
#define MY_COMPANY_END    }                     // end of the MyCompany namespace
#define MY_LIBRARY_BEGIN  namespace MyLibrary { // begin of the MyLibrary namespace
#define MY_LIBRARY_END    }                     // end of the MyLibrary namespace

This also removes the need for comments near the closing brace of the namespace (Did you ever scroll down to the bottom of a large source file and tried to add/remove/balance braces that were missing comments about which brace closes which scope? Not fun.).

MY_COMPANY_BEGIN
MY_LIBRARY_BEGIN

class X { };

class Y { };

MY_LIBRARY_END
MY_COMPANY_END

If you want to put all namespace declarations on a single line you can do that as well with a bit of (pretty ugly) preprocessor magic:

// helper macros for variadic macro overloading
#define VA_HELPER_EXPAND(_X)                    _X  // workaround for Visual Studio
#define VA_COUNT_HELPER(_1, _2, _3, _4, _5, _6, _Count, ...) _Count
#define VA_COUNT(...)                           VA_HELPER_EXPAND(VA_COUNT_HELPER(__VA_ARGS__, 6, 5, 4, 3, 2, 1))
#define VA_SELECT_CAT(_Name, _Count, ...)       VA_HELPER_EXPAND(_Name##_Count(__VA_ARGS__))
#define VA_SELECT_HELPER(_Name, _Count, ...)    VA_SELECT_CAT(_Name, _Count, __VA_ARGS__)
#define VA_SELECT(_Name, ...)                   VA_SELECT_HELPER(_Name, VA_COUNT(__VA_ARGS__), __VA_ARGS__)

// overloads for NAMESPACE_BEGIN
#define NAMESPACE_BEGIN_HELPER1(_Ns1)             namespace _Ns1 {
#define NAMESPACE_BEGIN_HELPER2(_Ns1, _Ns2)       namespace _Ns1 { NAMESPACE_BEGIN_HELPER1(_Ns2)
#define NAMESPACE_BEGIN_HELPER3(_Ns1, _Ns2, _Ns3) namespace _Ns1 { NAMESPACE_BEGIN_HELPER2(_Ns2, _Ns3)

// overloads for NAMESPACE_END
#define NAMESPACE_END_HELPER1(_Ns1)               }
#define NAMESPACE_END_HELPER2(_Ns1, _Ns2)         } NAMESPACE_END_HELPER1(_Ns2)
#define NAMESPACE_END_HELPER3(_Ns1, _Ns2, _Ns3)   } NAMESPACE_END_HELPER2(_Ns2, _Ns3)

// final macros
#define NAMESPACE_BEGIN(_Namespace, ...)    VA_SELECT(NAMESPACE_BEGIN_HELPER, _Namespace, __VA_ARGS__)
#define NAMESPACE_END(_Namespace, ...)      VA_SELECT(NAMESPACE_END_HELPER,   _Namespace, __VA_ARGS__)

Now you can do this:

NAMESPACE_BEGIN(Foo, Bar, Baz)

class X { };

NAMESPACE_END(Baz, Bar, Foo) // order doesn't matter, NAMESPACE_END(a, b, c) would work equally well

Foo::Bar::Baz::X x;

For nesting deeper than three levels you would have to add helper macros up to the desired count.

Community
  • 1
  • 1
Max Truxa
  • 3,308
  • 25
  • 38
  • 2
    As much as I dislike `#define`s I'm quite impressed by that preprocessor magic... only if I din't have to add additional helper macros for deeper nesting... well, I'm not going to use it anyway so... – galdin Mar 11 '17 at 20:33
13

C++ namespaces are used to group interfaces, not to divide components or express political division.

The standard goes out of its way to forbid Java-like use of namespaces. For example, namespace aliases provide a way to easily use deeply-nested or long namespace names.

namespace a {
namespace b {
namespace c {}
}
}

namespace nsc = a::b::c;

But namespace nsc {} would then be an error, because a namespace may only be defined using its original-namespace-name. Essentially the standard makes things easy for the user of such a library but hard for the implementer. This discourages people from writing such things but mitigates the effects if they do.

You should have one namespace per interface defined by a set of related classes and functions. Internal or optional sub-interfaces might go into nested namespaces. But more than two levels deep should be a very serious red flag.

Consider using underscore characters and identifier prefixes where the :: operator isn't needed.

Potatoswatter
  • 134,909
  • 25
  • 265
  • 421
  • 20
    Ok, so what about Windows::UI::Xaml and Windows::UI::Xaml::Controls::Primitives namespaces in Win8 development? I think Microsoft's usage of namespaces makes sense and it is indeed deeper than just 2 Levels. – Beachwalker Jul 26 '12 at 20:18
  • 3
    Using less than 2 levels is a red flag and using 3 or 4 is perfectly fine. Trying to achieve a flat namespace hierarchy when it does not makes sense defeats the very purpose of namespaces - avoiding name clashes. I agree that you should have one level for an interface and another one for subinterfaces and internals. But around that you need at least one more level for the company namespace (for small to medium companies) or two for company and division (for big companies). Otherwise your interface namespaces will clash with the ones from other interfaces with the same name developed elsewhere – Kaiserludi Aug 16 '18 at 12:56
  • @Kaiserludi What is the technical advantage of `company::division` over `company_division`? – Potatoswatter Aug 16 '18 at 12:58
  • @Potatoswatter Inside company::anotherDivsion you can just use the shorter 'division'. to refer to company::division even within headers where you should strongly avoid polluting higher level namespaces by the use of 'using namespace'. Outside of the company namespace you can still do a 'using namespace company;' when the division names don't collide with any other namespaces in your scope, but when the interface names inside some of the division namespace do collide so that you can't do 'using namespace company_division;'. – Kaiserludi Aug 16 '18 at 14:07
  • @Kaiserludi In other words, there are no benefits regarding ADL or other aspects of lookup, but it's for saving the keystrokes in `company` when referring to the inner namespace. And, this typing/brevity problem is already solved by namespace aliases. – Potatoswatter Aug 16 '18 at 14:14
  • 3
    @Potatoswatter The point is that you get it practically for free (company::division isn't any longer than company_division) and don't have to define an extra namespace alias first to use it. – Kaiserludi Aug 16 '18 at 14:35
7

No, and please don't do that.

The purpose of namespaces is primarily resolving conflicts in the global namespace.

A secondary purpose is local abbreviation of symbols; e.g. a complex UpdateUI method may use an using namespace WndUI to use shorter symbols.

I'm on a 1.3MLoc project, and the only namespaces we have are:

  • imported external COM libraries (mainly to isolate header conflicts between #import and #include windows.h)
  • One level of "public API" namespaces for certain aspects (UI, DB access etc.)
  • "Implementation Detail" namespaces that are not part of the public API (anonymous namespaces in .cpp's, or ModuleDetailHereBeTygers namespaces in header-only libs)
  • enums are the biggest problem in my experience. They pollute like crazy.
  • I still feel it's entirely too many namespaces

In this project, class names etc. use a two- or three-letter "region" code (e.g. CDBNode instead of DB::CNode). If you prefer the latter, there's room for a second level of "public" namespaces, but no more.

Class-specific enums etc. can be members of those classes (though I agree this is not always good, and it's sometimes hard to say whether you should)

There's rarely need for a "company" namespace either, except if you are having big problems with 3rd party libraries that are distributed as binary, don't provide their own namespace, and can't be easily put into one (e.g. in a binary distribution). Still, in my experience forcing them into a namespace is much easier to do.


[edit] As per Stegi's follow-up question:

Ok, so what about Windows::UI::Xaml and Windows::UI::Xaml::Controls::Primitives namespaces in Win8 development? I think Microsoft's usage of namespaces makes sense and it is indeed deeper than just 2 Levels

Sorry if I wasn't clear enough: Two levels isn't an hard limit, and more isn't intrinsically bad. I just wanted to point out that you rarely need more than two, from my experience, even on a large code base. Nesting deeper or more shallow is a tradeoff.

Now, the Microsoft case is arguably different. Presumably a much larger team, and all the code is library.

I'd assume Microsoft is imitating here the success of the .NET Library, where namespaces contribute to the discoverability of the extensive library. (.NET has about 18000 types.)

I'd further assume that there is an optimal (order of magnitude of) symbols in a namespace. say, 1 doesn't make sense, 100 sounds right, 10000 is clearly to much.


TL;DR: It's a tradeoff, and we don't have hard numbers. Play safe, don't overdo in any direction. The "Don't do that" comes merely from the "You have problems with that, I'd have problems with that, and I don't see a reason why you'd need it.".

AndyG
  • 39,700
  • 8
  • 109
  • 143
peterchen
  • 40,917
  • 20
  • 104
  • 186
  • 11
    Ok, so what about Windows::UI::Xaml and Windows::UI::Xaml::Controls::Primitives namespaces in Win8 development? I think Microsoft's usage of namespaces makes sense and it is indeed deeper than just 2 Levels. – Beachwalker Jul 26 '12 at 20:19
  • 2
    If I need global-access constants, I like to put them in a namespace with a name like `Constants`, then create nested namespaces with appropriate names to categorise the constants; if necessary, I then use further namespaces to prevent name collisions. This `Constants` namespace is itself contained in a catch-all namespace for the program's system code, with a name such as `SysData`. This creates a fully-qualified name containing three or four namespaces (such as `SysData::Constants::ErrorMessages`, `SysData::Constants::Ailments::Bitflags`, or `SysData::Defaults::Engine::TextSystem`). – Justin Time - Reinstate Monica Apr 12 '16 at 17:54
  • 1
    When the constants are required in actual code, any function that needs them uses a `using` directive to bring in the appropriate names, minimising the possibility of conflicting names. I find it improves readability, and helps document any given code block's dependencies. Apart from constants, I tend to try and keep it to two namespaces if possible (such as `SysData::Exceptions` and `SysData::Classes`). – Justin Time - Reinstate Monica Apr 12 '16 at 18:03
  • 2
    As a whole, I'd say that in general cases, it's best to use a minimal number of nested namespaces, but if you need global objects for some reason (whether constant or mutable, preferably the former), multiple nested namespaces should be used to separate them into appropriate categories, both to document their usage and minimise potential name collisions. – Justin Time - Reinstate Monica Apr 12 '16 at 18:05
  • 3
    -1 for "please don't do this" without *objective* reasons why (despite the clarifications later). The language supports nested namespaces and a project may have good reasons for using them. A discussion of possible such reasons and any *concrete, objective* disadvantages to doing so would reverse my downvote. – TypeIA Nov 30 '17 at 19:33
  • "enums are the biggest problem in my experience. They pollute like crazy." Well, just put each enum in its own namespace and don't ever use 'using' on enum namespaces, but only access enum values via 'EnumNamespaceName::enumValue'. That way they don't pollute your project namespace(s). – Kaiserludi Aug 16 '18 at 14:14
5

Here a quote from Lzz (Lazy C++) docs:

Lzz recognizes the following C++ constructs:

namespace definition

An unnamed namespace and all enclosed declarations are output to the source file. This rule overrides all others.

The name of a named namespace may be qualified.

   namespace A::B { typedef int I; }

is equivalent to:

   namespace A { namespace B { typedef int I; } }

Of course the quality of sources that depends on such tools is debatable... I would say it's more a curiosity, showing that the syntax disease induced by C++ can take many form (I have mine, too...)

Andrii Kalytiiuk
  • 1,501
  • 14
  • 26
CapelliC
  • 59,646
  • 5
  • 47
  • 90
3

This paper covers the subject rather well: Namespace Paper

Which basically boils down this. The longer your namespaces are the more likely the chance that people are going to use the using namespace directive.

So looking at the following code you can see an example where this will hurt you:

namespace abc { namespace testing {
    class myClass {};
}}

namespace def { namespace testing {
    class defClass { };
}}

using namespace abc;
//using namespace def;

int main(int, char**) {
    testing::myClass classInit{};
}

This code will compile fine, however, if you uncomment the line //using namespace def; then the "testing" namespace will become ambiguous and you will have naming collisions. This means that your code base can go from stable to unstable by including a 3rd party library.

In C#, even if you were to use using abc; and using def; the compiler is able to recognize that testing::myClass or even just myClass is only in the abc::testing namespace, but C++ will not recognize this and it is detected as a collision.

Questionable
  • 768
  • 5
  • 26
2

Both standards (C++2003 and C++11) are very explicit that the name of the namespace is an identifier. This means that explicit nested headers are required.

My impression that this is not a big deal to allow placing qualified identifier besides a simple name of the namespace, but for some reason this is not allowed.

Kirill Kobelev
  • 10,252
  • 6
  • 30
  • 51
0

Yes, you will have to do it like

namespace A{ 
namespace B{
namespace C{} 
} 
}

However, you are trying to use the namespaces in a way they are not supposed to be used. Check this question, maybe you will find it useful.

Community
  • 1
  • 1
SingerOfTheFall
  • 29,228
  • 8
  • 68
  • 105
0

You can use this syntax:

namespace MyCompany {
  namespace MyModule {
    namespace MyModulePart //e.g. Input {
      namespace MySubModulePart {
        namespace ... {
          class MyClass;
        }
      }
    }
  }
}

// Here is where the magic happens
class MyCompany::MyModule::MyModulePart::MySubModulePart::MyYouGetTheIdeaModule::MyClass {
    ...
};

Note this syntax is valid even in C++98 and it is almost similar to what is now available in C++17 with nested namespace definitions.

Happy unnesting!

Sources:

smac89
  • 39,374
  • 15
  • 132
  • 179
  • That is the sytax mentioned in the question where a better solution is searched for instead. Now, with C++17 is a valid alternative available as stated by the accepted answer. Sorry, downvote for not reading the question and answer. – Beachwalker Jan 03 '18 at 07:22
  • @Beachwalker let's not get caught up on syntax. The namespace declaration above could as well be the same as in the accepted answer. The main point I wanted to highlight by this answer is what the OP had said he missed, and what I did below that namespace mess. As far as I can see everyone seems to have been focused on declaring everything within the namespace, whereas my answer takes you out of the nested mess and I'm sure OP would have appreciated this syntax had anyone mentioned it 4 years ago when this question was first asked. – smac89 Jan 03 '18 at 13:57
0

[ EDIT: ]
Since c++17 nested namespaces are supported as a standard language feature (https://en.wikipedia.org/wiki/C%2B%2B17). As of now, this feature is not supported in g++8, but it can be found the in clang++6.0 compiler.


[ CONCLUSION: ]
Use clang++6.0 -std=c++17 as your default compilation command. Then everything should work fine - and you will be able to compile with namespace OuterNS::InnerNS1::InnerNS2 { ... } in your files.


[ ORIGINAL ANSWER: ]
Since this question is a bit old, I will assume that you have moved on. But for others, who are still looking for an answer, I came up with the following idea:

Emacs buffers showing main file, namespace files, compilation command/result, and command-line execution.

(Might I make an advertisement for Emacs here :) ?) Posting an image is far easier, and more readable, than to simply post code. I do not intend to provide a full-flegded anwer of all corner cases, simply I meant to give some inspiration. (I totally support C# and feel that in many cases C++ should adopt some OOP features, since C# is popular mainly due to its compared ease of use).

alexpanter
  • 1,222
  • 10
  • 25
  • Update: Since C++17 has nested namespacing (http://www.nuonsoft.com/blog/2017/08/01/c17-nested-namespaces/), it would seem that my answer is no longer relevant, unless if you are using older versions of C++. – alexpanter Oct 22 '18 at 07:38
  • 3
    As much as I love Emacs, posting an image is not ideal. It eludes text search / indexing, and also makes your answer hard to access for visually impaired visitors. – Heinrich supports Monica Jan 21 '19 at 14:47