When to use nested namespaces in C++

Main reason to use namespaces is to prevent name clashes, but there is also an option to nest them. It is less often taught what purposes nested namespaces can serve. C++ Core Guidelines recommends we reflect logical structure with namespaces but what exactly does that mean was not well explained at the time of writing. Here is my interpretation of the role of nested namespaces in C++.

C# has namespaces too but besides simply preventing name clashes with different libraries, they also have a role in organizing names in logical hierarchy. This codified hierarchy is then used to selectively import code from outside the current file, similar to what include statement does in C++. Because of that, nested namespaces are used extensively in C#, but C++ namespaces do not assume such responsibility. In code we can often observe how programmers apply instincts learnt from C# directly to C++, but because of the differences between the purposes of these two homonyms, C# best practices should be reconsidered for C++ namespaces.

I think it is best to apply them selectively where they fulfill a definable purpose, not just mindlessly everywhere. Nothing that serves no purpose should be in the code, because everything has downsides and should therefore have some upsides first.

One of the downsides of a name being in some nested namespace instead of in the library's main namespace is that it is harder to find. Intellisense will suggest the names from the namespace only if you type it in. If there are many namespaces nested inside the main namespace of a library and the name that is being looked for is inside that one, programmer that relies on intellisense will not see it immediately. Typing all nested namespaces is needed in order to find the name, because it is not always clear where to expect them.

Not finding an existing thing is not only problematic when using the library, but perhaps even more so when writing it. If a thing exists and you write a new one, you can only hope someone will catch that on code review. It is easy to miss an existing construct even without additional hindrances.

Compilers too might have similar problems with visibility. Conventional wisdom says we should not put helper functions in separate namespaces from the names they operate on. That is to aid argument dependent lookup.

Writing the namespace in front of everything is also tedious and hard to read because it gets repetitious really quickly. The mind works against the programer in this case, because as soon as there is a pattern, brain shuts off reading and engages assuming that the rest is just the same pattern repeated. Repeating long::strings_of::namespace::names multiple times in a row will cause readers of the code to skip the end of the line and assume it is what they think it is, and that will allow mistakes to crawl in easier.

Beside nested namespaces being a hindrance when reading, they are mighty annoying to write as well. The way to alleviate these problems is to declare using namespace in a file, but then what is the point of having the nested namespace in the first place?

So, after all this negativity about nested namespace, when are they useful?

Same primary problem: name collisions, but this time the ones inside the library. It is not always a design problem. As the codebase becomes larger and larger, there is a possibility that there will be name collisions inside the library itself. In that case you are left with two options: either rename one of the names, making it less intuitive than it could have been, or put it into a dedicated namespace. This is, after all, the core intent of namespaces feature. If I steal an example from Howard Hinnant, the lead author on the std::chrono proposal, where he defended the nested namespace chrono: "Imagine if we add calendrical services that include an abbreviation for December: dec. This would directly conflict with ios_base& dec(ios_base& str); in <ios>." By the way, having nested namespace for std::chrono was "not his first choice".

Avoiding the need for argument-dependent lookup, which will sometimes confuse you and other times simply not work. If the user doesn't import namespace containing functions like string literals or some non-member operator overloads, they can't be used in a way that is not utterly awkward. They don't always resolve by argument-dependent lookup, for example when none of the arguments is defined in that namespace, so if they were not in their own dedicated nested namespace that you can pull in, user would need to bring in the whole library's namespace just for them.

To visibly separate sections of code that are not meant to be used in normal conditions. Examples include deprecated, experimental, internal code, etc. Namespace "experimental" is used by standard library, Google uses "internal" for stuff you should not see and use. Deprecated will soon become obsolete by utilising [[deprecated]] tag in C++17, but surely there are many other special cases out there. You cannot use such a name by mistake, you had to be aware what you were doing at the time of coding. And once used, these cases are glaringly obvious in client code as well as within the library so they are easy to find when needed.

If there is a collection of constructs that are so related that they will use the same word in the name anyway, nested namespaces can be a nice approach. In this case, typing the namespace in front of a name has a role of not only grouping, but also explaining the context of the call. As an example: acceleration() doesn't say a lot about what the purpose of the call is, while law::acceleration does it better. Or unset() and exception::unset(). It is so important to write that prefix, that if it wasn't there, it would have to be added to the name itself to bring out the purpose. Instead of writing law_of_acceleration, especially if you implement many such laws, it is more convenient to define them in nested namespace "law". An example of this can be observed in C++ threading features for example. In standard library there is get_id(), which tells you nothing, but prepending this_thread::get_id() creates a ton of difference in understanding of the code. In this use case, the intellisense, which was used earlier as a detractor from using nested namespaces too much, can be leveraged in a useful manner. If I want to see what exceptions are available to me I can just write exceptions:: and wait half a second. This only works because it is very clear what goes into this namespace and what not. You can recognise cases like that if something could have been implemented as a degenerated kind of class that only has public static member functions and nothing else, yet the function names would seem meaningless without the context.

And final thing I could think of is to use them to store constant values in them. This is because there are bajillion constants in the world, which to some extent is probably reflected in your project. To not pollute the namespace with numerous constant defines you can sweep them under one nested namespace and help the user actually get more out of intellisense quicker.


Previous: Peformance implications of compacting vector elements
Next: Retrieving iterator value type