C++ – Is including headers inside a namespace always a bad idea

cincludenamespace

The replies in this post come very strongly against including headers inside a namespace and Doxygen is confused if that is done (which suggests that its team did not consider that usage either). I would like to ask whether including headers inside a namespace is justified in the following case.

I am developing a header-only framework for exploring a certain family of algorithms. Once first released, extensions in the form of header files will be contributed by the members of the research community. A contributed header file may implement a new algorithm or a policy of an existing algorithm or something else. Depending on what the new header implements, it will be placed in the relevant folder.

The namespaces in the framework mimic the folder structure. So, consider a folder A/B/ of the framework and suppose that the headers x.h, y.h and z.h are in that folder. Without including headers inside namespaces, the file x.h would look something like this:

namespace N { // The namespace in which the whole framework resides
namespace A { // Folder A/
namespace B { // Folder A/B/
namespace X { // The facilities provided by x.h are related
    ... // Definition of the facilities
}
}
}
}

The files y.h and z.h would begin with opening four namespaces as well. Furthermore, if a user contributes w.h to this folder, he will need to remember to open the namespaces N, A and B to not break the design.

In the alternative (and better in my opinion) design, each folder has a headers.h file as follows.

A/B/headers.h is:

namespace B {
    #include "x.h"
    #include "y.h"
    #include "z.h"
}

A/headers.h is:

namespace A {
    #include "B/headers.h"
    ... // includes headers.h of other sub-folders of A/
}

Then x.h looks like this

namespace X { // The facilities provided by x.h are related
    ...
}

Are there strong reasons not to use this alternative design?

Please note that the library is meant to be included into the .cpp as a whole (i.e. the top-level header.h is included). This does not incur long compile times, because the library is heavily templated and only a few templates (i.e. the algorithm under study, its policies and the related facilities) end up instantiated. Hence, I do not worry about the possibility of wrongly including an individual header without its namespace context.

There are no dependencies at the bottom (i.e. leaf) level, where all the headers implementing the actual facilities (such as x.h, y.h and z.h in the example) are located. So, a headers.h at the bottom level (such as A/B/headers.h in the example) may list the included headers in alphabetical order. A headers.h at a non-bottom level (such as A/headers.h in the example) includes headers.h from each sub-folder in the order that respects dependencies. That order is fixed (e.g. all the policies are included before all the algorithms) and the users will not need to deal with it.

Best Answer

Reasons this is a bad idea:

  • Knowledge about your design is now partly stored in the directory structure. This isn't a good place for design logic to be placed.
    • What if someone just receives the file x.h? They won't be able to tell from the code itself what its classification is, because only with the full directory and all files can someone tell that x.h is properly located within N -> A -> B
    • There may be errors from accidentally putting something in the wrong place.
    • Logically, you would like someone who only has permission to use the parent to be able to extend it, but now you can only extend something that you have permission to modify it.
  • You can't add a new element just by adding a new header. Instead, you also have to update the appropriate "headers.h" file, leading to extra complexity and potential conflicts when adding new things.
  • You are making a design decision that the entire header file must be included forever. In your question, you note that this is not a problem right now. But are you really sure that there will never, ever be a time in the future where someone will want to include individual headers?
  • You are making a design decision that there cannot ever be significant interdependencies. Again, this is not true now, but are you really so sure it will never be true?
  • You are doing something weird which is a downside in itself, since now everyone using this code has to take time to learn your unique design, which no one else uses.

I would avoid this. Also, is it possible you should not be using nested namespaces?

Related Topic