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
[ 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:
(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).
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:
#import
and #include windows.h
)ModuleDetailHereBeTygers
namespaces in
header-only libs) 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.".
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:
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
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...)