Sub-Namespaces for organizing features: Yes or No?

I've been working on a personal library called J118 for a while now, and it's starting to gain in size. It's just a personal project I do for fun and to learn new things. I'm getting to a point to where I have many related things that could be grouped together. I was wondering if it would be a bad idea to start implementing Sub-Namespaces for related features to help organize the library.

For example:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
namespace J118
{
namespace Concurrency
{
  class Thread
  {
    ...
  }

  class PeriodicThread : public Thread
  {
    ...
  }

  class Mutex
  {
    ...
  }
}
}




I'm going to add my own cross-platform window manager soon and want an opinion before I start so I won't need to refactor down the line. Thank for all your input!

I say no. Use namespaces to avoid naming conflicts, not to reflect project organization. For example, lately I found myself needing this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
namespace Hashes{
namespace Digests{

class SHA256{ /*...*/ };

class RIPEMD160{ /*...*/ };

}

namespace Algorithms{

class SHA256{
    //...
public:
    //...
    Digests::SHA256 result();
};

class RIPEMD160{
    //...
public:
    //...
    Digests::RIPEMD160 result();
};

}
}
Last edited on
> Sub-Namespaces for organizing features: Yes or No?

Yes.
JLBorges can you elaborate why?

Also I was considering doing sub-namespaces because I see the boost library doing it.
One interesting feature added with C++17 is the ability to define nested namespaces as X::Y. This should make what you want to do easier.

https://www.learncpp.com/cpp-tutorial/4-3b-namespaces/
http://open-std.org/JTC1/SC22/WG21/docs/papers/2017/p0816r0.pdf

Titus Winters wrote:
The guidance for users should be single-level broad namespaces - namespaces are best used to
disambiguate between the local project and imported projects. Because of the promiscuity of name
lookup rules, nested namespaces should not be used as an attempt to introduce partitions in the current
project - it doesn't work that way.
Last edited on
I see the boost library doing it.

One thing to keep in mind is that Boost isn't a single library but rather a collection of libraries, independently-developed.
> JLBorges can you elaborate why?

See the discussion under:
58. Keep types and functions in separate namespaces unless they're specifically intended to work together.

Summary

Help prevent name lookup accidents: Isolate types from unintentional argument-dependent lookup (ADL, also known as Koenig lookup), and encourage intentional ADL, by putting them in their own namespaces (along with their directly related nonmember functions; see Item 57). Avoid putting a type into the same namespace as a templated function or operator.

in 'C++ Coding Standards: 101 Rules, Guidelines, and Best Practices' by Sutter and Alexandrescu

A more elaborate explanation with more examples is available in this proposal to "render Item 58 above obsolete".
http://open-std.org/JTC1/SC22/WG21/docs/papers/2018/p0934r0.pdf
In addition to what JLBorges said, in large projects, it can help document dependencies between code modules. If I'm looking at code in the MikeyBoy::control namespace, and I can see that it's using classes in the MikeyBoy::data namespace, then I can see at a glance that the control library has a dependency on the data library, and exactly where those dependencies are and why they're there.

And when you're working on a codebase that can take ~20 minutes to build, managing dependencies becomes important!
Last edited on
Documenting dependencies. That is something I hadn't considered. Thanks for mentioning it, MikeyBoy.
Topic archived. No new replies allowed.