3

The first language that I truly learned was Java. In it, it is very syntactically easy to nest classes in an essentially arbitrarily complex package hierarchy, which keeps the code organized. It is easy because the syntactic clutter of a deeply nested hierarchy is all placed neatly at the top of the file with import and package declarations, and then classes are referenced solely by their primary name and nothing else in the code body.

In C++, this is not the case. There is no package declaration for a file, instead keeping the namespace name visible in all references to that namespace's contents is preferred. This is fine for only lightly nested namespaces (e.g. std::chrono), but becomes very cumbersome very quickly if one tries java-style package nesting (e.g. game_name::server::world::actor::messages::ChatMessage). Of course, one can add using namespace declarations in addition to #include, but this is a form of code duplication and feels about as cluttered. It also is a horrific idea for header code (which is often non-trivial, such as in the case of templates).

In C++, how can I allow for the powerful organization found with deeply nested namespaces, but without introducing non-trivial syntactic clutter?

The best idea that I have for this is to keep most to all of my program's code in a few simple namespaces (e.g. game and game::detail), but this creates an entirely new issue where there are two separate hierarchies — one for namespaces, and another for the file system.

  • 1
    Include+using namespace might be redundant, but it really does help with this. That seems like the right approach, but I'm not an experience C++ programmer. The usual warnings about using namespace only really apply when importing namespaces you don't control, where new API additions can cause breakages. – Alexander - Reinstate Monica Sep 28 at 1:04
  • @Alexander That doesn't help with headers and spamming gigantic names in those, as using namespace should not be a thing in headers. – john01dav Sep 28 at 1:31
  • 2
    I think you can scope your using to a new scope, and put your header's contents within that – Alexander - Reinstate Monica Sep 28 at 2:00
  • Good question, clearly about readability and the DRY principle, which are perfectly on-topic for this site. I have no idea why the question got a downvote. – Doc Brown Sep 28 at 7:45
  • 1
    @john01dav Dont think the namespace as some kind of file grouping mechanisms like folders. Consider them more as ways to modularize your code. Each namespace represents a module. Now if the module is kept in 1 single folder or is split across many folders is an implementation detail. To the consumer, it is just 1 module – Sisir Oct 4 at 7:21
7

this creates an entirely new issue where there are two separate hierarchies — one for namespaces, and another for the file system.

That's not an issue at all though, it's perfectly normal.

Coupling the namespace and filesystem structures is (so far as I know) unique to Java. Trying to import this idiom into any other language where it isn't already idiomatic is a bad idea. (I'm trying hard to be diplomatic as I'm not entirely convinced it's a good idea in Java either, but of course the damage is baked in there).

allow for the powerful organization found with deeply nested namespaces

Citation needed!

Nesting is a pretty restrictive type of organization. Your example has messages nested inside the server code; does that mean they're only used for communication with itself? Does the client have its own messages? How do they talk to each other?

Nesting makes it artificially hard to express anything shared outside its strict hierarchy.

Other approaches include splitting your code into components, which are usually layered and composed rather than nested, and fit naturally with a flatter layout.

  • "Coupling the namespace and filesystem structures is unique to Java" +1 for this. – Sisir Oct 4 at 7:17
  • Take for example the case of C# which is also modern language but there you will find C++ styled namespace organization – Sisir Oct 4 at 7:18
4

One way to handle it: Don't do it.

In your example, you could have a namespace game_name::server and leave it at that. Don't reuse names for top level objects obviously. But they are confusing anyway. They change their meaning totally if you change a namespace.

Ask yourself if you actually gain anything from the use of namespaces. Not theoretically, but practically. If you don't, don't use them.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.