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

I switched from C ++ to Java and C # and find that using namespaces / packages is much better (well structured). Then I returned to C ++ and tried to use namespaces the same way, but the required syntax is terrible inside the header file.

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

It also seems strange to me (to avoid a deep indent):

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

Is there a shorter way to express the above thing? I'm missing something like

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

Update

Well, some say the concept of usage in Java / C # and C ++ is different. Indeed? I think that (dynamic) class loading is not the only goal for namespaces (this is a very technically sound prospect). Why don't I use it for readability and structuring, for example, think of "IntelliSense".

There is currently no logic / glue between the namespace and what you can find there. Java and C # do this much better ... Why include an <iostream> and have a std ? Well, if you say that logic should rely on the header to include, why does #include not use the friendly IntelliSense syntax, like #include <std::io::stream> or <std/io/stream> ? I think the lack of structuring in libs by default is one C ++ weakness compared to Java / C #.

If the uniqueness for avid conflicts is one point (which is also a C # and Java point), itโ€™s a good idea to use the project name or company name as the namespace, don't you think?

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

Update 2

Most users say it's silly to create a deeper nesting than two levels. So, what about Windows: UI :: Xaml and Windows :: UI :: Xaml :: Controls :: Primitives namespaces in Win8 development? I think that using the Microsoft namespace makes sense, and it's really deeper than just 2 levels. I think larger libraries / projects require a deeper nesting (I hate class names like ExtraLongClassNameBecauseEveryThingIsInTheSameNameSpace ... then you could put everything in a global namespace too.)

Update 3 - Conclusion

Most say don't do it, but ... even the gain has a deeper nesting, and then one or two levels. Yes, this is a library, but: If you want to use reusable code, treat your own code as a library that you give to someone else. I also use a deeper nesting for search purposes using namespaces.

+57
c ++ syntax namespaces
Jul 06 '12 at 8:17
source share
8 answers

C ++ 17 can simplify the definition of a nested namespace:

 namespace A::B::C { } 

equivalently

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

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

+67
Jan 19 '15 at 10:25
source share

To avoid deep indentation, I usually do this as follows:

 namespace A { namespace B { namespace C { class X { // ... }; }}} 
+21
Dec 12 '14 at 15:40
source share

C ++ namespaces are used to group interfaces, and not to separate components or express political separation.

The standard prohibits the use of a Java namespace. For example, namespace aliases provide the ability to easily use nested or long name names.

 namespace a { namespace b { namespace c {} } } namespace nsc = a::b::c; 

But namespace nsc {} will be an error because the namespace can only be determined using namespace namespace namespace. In fact, this standard makes it easier for users to use such a library, but for the developer it is difficult. This prevents people from writing such things, but mitigates the consequences if they do.

You must have one namespace for each interface, defined by a set of related classes and functions. Internal or additional sub-interfaces may be part of nested namespaces. But more than two levels in depth should be a very serious red flag.

Consider using underscores and identifier prefixes where the :: operator is not needed.

+12
Jul 06 2018-12-12T00:
source share

No, and please do not do this.

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

The secondary target is a local abbreviation of characters; for example, the sophisticated UpdateUI method may use using namespace WndUI to use shorter characters.

I am working 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 (user interface, database access, etc.).
  • "Implementing details" of namespaces that are not part of the public API (anonymous namespaces in .cpp, or ModuleDetailHereBeTygers namespaces in header-only)
  • transfers are the biggest problem in my experience. They pollute like crazy.
  • I still feel that there are too many namespaces.

In this project, class names, etc. use two- or three-letter "regional" code (for example, CDBNode instead of DB::CNode ). If you prefer the latter, there is room for a second level of "public" namespaces, but nothing more.

Enumerations specific to a class, etc., can be members of these classes (although I agree that this is not always good, and it is sometimes difficult to say if you need to)

The company namespace is also rarely required, unless you have big problems with third-party libraries that are distributed as binary, do not provide your own namespace, and cannot easily be placed in one (for example, in a binary distribution). However, in my experience, getting them into the namespace is much easier.




[edit] According to the following Stegi question:

So, what about the Windows :: UI :: Xaml and Windows :: UI :: Xaml :: Controls :: Primitives namespaces in Win8 development? I think using the Microsoft namespace makes sense, and itโ€™s really deeper than just 2 levels

Sorry if I was not clear enough: the two levels are not a hard limit, and are no longer internally bad. I just wanted to point out that you rarely need more than two, in my experience, even on a large code base. Investing deeper or finer is a compromise.

Now, Microsoft's case may be different. Presumably a much larger team, and all the code is a library.

I would suggest that Microsoft mimics the success of a .NET library, where namespaces contribute to the discovery of a vast library. (.NET has about 18,000 types.)

I would suggest that there are optimal (ordinal values) characters in the namespace. let's say 1 does not make sense, 100 sounds are right, 10,000 are clearly a lot.




TL; DR: This is a compromise, and we have no hard numbers. Play in a safe place, do not overdo it in any direction. โ€œDonโ€™t do thisโ€ comes simply from โ€œYou have a problem with this, I would have a problem with this, and I see no reason why you need this.โ€

+7
Jul 06 '12 at 9:00
source share

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

Declaring namespaces is one of the very rare cases in C ++ where I really like using #define s.

 #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 

It also eliminates the need for comments next to the closing bracket of the namespace (have you ever scrolled down to the end of a large source file and tried to add / remove / balance curly braces that did not have comments about which curly brace closes this area? Not fun. )

 MY_COMPANY_BEGIN MY_LIBRARY_BEGIN class X { }; class Y { }; MY_LIBRARY_END MY_COMPANY_END 

If you want to put all the namespace declarations on one line, you can do this also with a small (rather ugly) magic preprocessor:

 // 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 more than three levels, you will need to add auxiliary macros to the desired number.

+6
Dec 17 '14 at 19:09
source share

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

Lzz recognizes the following C ++ constructs:

namespace definition

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

You can name the named namespace.

  namespace A::B { typedef int I; } 

equivalent to:

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

Of course, the quality of sources dependent on such tools is controversial ... I would say that this is more curiosity, showing that the syntactic disease caused by C ++ can take many forms (I also have ...)

+4
Jul 06 2018-12-12T00:
source share

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

My impression is that this is not a big problem, allowing you to place a qualified identifier in addition to the simple namespace name, but for some reason this is not allowed.

+2
Jul 6 '12 at 8:22
source share

Yes, you have to do it like

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

However, you are trying to use namespaces in a way that they should not be used. Check this question out, you might find it helpful.

+1
Jul 06
source share



All Articles