It's implementation-defined whether or not other header files internally use a particular standard header file.
In general, if the code file needs something that is #include'd with a particular header, then directly include that header file, and don't rely on other unrelated standard header files to include it.
Although the standard dictates particular inclusions of one standard header file in another -- mostly because it's obvious that they would need to be included and often the included header files are ones you don't usually include yourself anyway -- in the end an implementation is allowed to do pretty much whatever it wants. So with the online g++ compiler this compiles:
1 2 3 4 5 6
#include <iostream>
int main() {
system("ls"); // from <cstdlib> (don't even need std::)
std::string s{"Hello"}; // from <string>
std::cout << '\n' << char(tolower(s[0])) << '\n'; // tolower from <cctype>
}
However, you should of course include the proper header files for everything that you need. Unfortunately, the above situation means that you won't always be told if you are missing a header file.