Say we have this header file:
#pragma once
#include
class MyClass
{
public:
MyClass(double);
/* ... */
private:
As others have said, it is safer to directly include the files you use, in terms of being protected from future changes to the file you're relying on to forward it.
It is also generally considered cleaner to have your dependencies immediately there. If you want to check what this "MyClass" object is, you want to just scroll to the top and ask your IDE to take you to the relevant header.
It's worth noting that it's safe to include the same standard header multiple times, as provided by a standard library guarantee. In practice, that means that the implementation of (in say clang's libc++) will start with an #include
guard. Modern compilers are so familiar with the include guard idiom (especially as applied by their own standard library implementations) that they can avoid even loading the files. So the only thing that you lose in exchange for that safety and clarity is having to type an extra dozen or so letters.
All that being agreed with everyone else, I have re-read it and I don't think your question was actually "Should I do this?" so much as "Why am I even allowed to not do this?" Or "Why doesn't the compiler insulate me from my includes' includes?"
There is one important exception to the "directly include what you use" rule. That is headers which, as part of their specification, include additional headers. For example
and
. One might say "why not just have the contents of
and
moved into
directly?" but there are clarity and compilation speed advantages to having the option of splitting them up if only one is needed. (And, no doubt for c++, there are historical reasons too) You can of course do this for your own headers too. (It's more of an Objective-C thing, but they have the same include mechanics and conventionally use them for umbrella headers, whose sole job is to include other files.)
There is another fundamental reason that headers your includes include get included. That is that, in general, your headers don't make sense without them. Suppose that your MyClass.hpp
file contains the following type synonym
using NumberPack = std::vector;
and the following self-descriptive function
NumberPack getFirstTenNumers();
Now suppose that another file includes MyClass.hpp
and has the following.
NumberPack counter = getFirstTenNumbers();
for (auto c : counter) {
std::cout << c << "\n"
}
What's going on here is that you may not want to write into your code that you're using
. That is an implementation detail that you don't want to have to worry about. NumberPack
could, as far as you're concerned, be implemented as some other container or an iterator or a generator type thing or something else, so long as it follows its spec. But the compiler needs to know what it actually is: it can't make effective use of parent dependencies without knowing what the grandparent dependency headers are. A side effect of that is that you get away with using them.
Or, of course, the third reason is just "Because that's not C++." Yes, one could have a language in which did not get second generation dependencies passed down, or you had to expressly request it. It's just that it would be a different language, and in particular would not fit into the old text include based style of c++ or friends.