Does the standard specify what headers include oth

2019-06-26 04:31发布

问题:

I was doing a online coding contest and my idea was to find a header which has a shorter name than <iostream> but includes <iostream>. Well, I didnt suceed until now, but this made me wonder:

Does the standard specify what headers include other headers?

For example, on <iostream> cplusplus states:

Including this header may automatically include other headers, such as <ios>, <streambuf>, <istream>, <ostream> and/or <iosfwd>.

However, when I look for <ios> there is no such statement as "This header might be included by <iostream>". For some headers I could imagine that they need to include others to work properly. And if this is the case, I would expect the standard to make some statement how the headers depend on each other (e.g. cyclic dependencies have to be avoided). Or does the standard just make sure that such dependencies do not exist and it is up to the implementation?

回答1:

As far as I know, the standard does not specify what headers include other headers - that's implementation defined and not something you should ever rely on. Include what you use.

Also, you may want to prefer http://cppreference.com/ over http://cplusplus.com/ as it is (IMHO) of much higher quality.



回答2:

The general rule about which headers may be included by other headers is: there are a few headers that are specified to be included automatically, and other than that, it depends on the implementation and does not need to be documented.

17.6.5.1 Conforming implementations [conforming]

17.6.5.2 Headers [res.on.headers]

1 A C++ header may include other C++ headers. A C++ header shall provide the declarations and definitions that appear in its synopsis. A C++ header shown in its synopsis as including other C++ headers shall provide the declarations and definitions that appear in the synopses of those other headers.

That rule about "shown in its synopsis as including other C++ headers" applies to:

  • <utility>, <string>, <array>, <deque>, <forward_list>, <list>, <vector>, <map>, <set>, <unordered_map>, <unordered_set>, <queue>, <stack>, <algorithm>, <random>, <valarray>, <regex> include <initializer_list>.
  • <bitset> includes <string>, <iosfwd>.
  • <iostream> includes <ios>, <streambuf>, <istream>, <ostream>.
  • <ios> includes <iosfwd>.

However, although e.g. <ios> is shown as including <iosfwd>, the implementation may be able to achieve the requirements without actually including it, and per [res.on.headers], that is just fine. For the most part, it doesn't make any difference whether the implementation includes the other headers, so long as the declared functions and types are made accessible.



回答3:

In general, no, the standard does not specify that headers must include other headers; it's up to the implementation to manage getting names from other headers when they are needed, and standard headers are allowed to include any other standard headers.

The one exception is the header <initializer_list>; headers that use initializer lists (containers, for example) are required to include that header.



回答4:

It depends on which version of the standard one is referring to. C++98 and C++03 make no requirement on headers including other headers.

Beginning with either C++11 or C++14, the standard does mandate that certain headers include other headers.

All versions of the standard have required that including the same header multiple times is safe.

So, if you know you need a particular header, and you're working on a compiler that implements an older standard, just #include the header.