Is there a better way to express nested namespaces in C++ within the header

C++SyntaxNamespaces

C++ Problem Overview


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.

C++ Solutions


Solution 1 - C++

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

Solution 2 - C++

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

namespace A { namespace B { namespace C
{
    class X
    {
        // ...
    };
}}}

Solution 3 - C++

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.

Solution 4 - C++

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.

Solution 5 - C++

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.".

Solution 6 - C++

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...)

Solution 7 - C++

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.

Solution 8 - C++

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.

Solution 9 - C++

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.

Solution 10 - C++

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:

Solution 11 - C++

[ 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).

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
QuestionBeachwalkerView Question on Stackoverflow
Solution 1 - C++W1M0RView Answer on Stackoverflow
Solution 2 - C++Kurt HutchinsonView Answer on Stackoverflow
Solution 3 - C++Max TruxaView Answer on Stackoverflow
Solution 4 - C++PotatoswatterView Answer on Stackoverflow
Solution 5 - C++peterchenView Answer on Stackoverflow
Solution 6 - C++CapelliCView Answer on Stackoverflow
Solution 7 - C++QuestionableView Answer on Stackoverflow
Solution 8 - C++Kirill KobelevView Answer on Stackoverflow
Solution 9 - C++SingerOfTheFallView Answer on Stackoverflow
Solution 10 - C++smac89View Answer on Stackoverflow
Solution 11 - C++alexpanterView Answer on Stackoverflow