In a previous post I’ve asked that your C++ header kindly refrain from polluting my name space. “User-facing” headers — the headers that expose the API of a library — should contain what is needed for the API declarations to compile, and no more. Within your header file, prefer forward references to nested includes where you can.
But this lean header must be complete. I should be able to compile a module that includes this header and no others. I can’t imagine there being any argument against this directive, although it’s not at all rare to find code that violates it.
What about inheriting nested includes? I.e., if you include a header that includes <string>, should your program include <string>? My vote is “yes”, since I believe it makes the code more self-documenting, and makes it easier for humans to see module inter-dependencies. Put another way, I don’t think it’s right to “piggy-back” on the include statements within a header, particularly if you refer to these items in code unrelated to that header. But I don’t see how this could be enforced.
One of my own practices makes me vulnerable to relying on nested rather than explicit includes is that, when I am cleaning up a code module, I will try to compile it with suspect headers commented out. The compiler is happy to benefit from nested headers, even if I’d prefer them to be explicit. So there is a little tension between “minimal” and “complete”.
Perhaps it goes without saying that I cringe every time I see a header file called something like common.h. What a bad idea, what a false optimization!