6

I've noticed that many people include iostream and ostream in C++ programs separately, like so:

#include <iostream>
#include <ostream>
int main()
{
}

Why would anyone do that? Since iostream inherits from ostream, it should include everything in it, right? Is there some obscure reason? What about simple (std::cout) code?

jackj
  • 63
  • 1
  • 4
  • note: the "duplicate" was later in time than this question, however it has more comprehensive answers so I have put the link that way around. – M.M Mar 17 '16 at 04:56

2 Answers2

7

Although stringstream inherits from iostream, it is not declared in the <iostream> header. The <iostream> header contains the definition of the iostream type along with the famous cout, cerr, cin, and clog types, but not other types that are iostreams (for example, file streams). For these, you do need to explicitly #include the requisite header files.

EDIT: In response to your revised question, I pulled up the C++ spec and interestingly it does not say that <iostream> has to include either <ostream> or <istream>. In fact, it could get away with just including <iosfwd>. Consequently, it's possible to #include <iostream> without actually getting a full class definition for either istream or ostream. Only explicitly including those headers can guarantee that the definitions of those classes, not just the forward-declarations, are visible.

templatetypedef
  • 362,284
  • 104
  • 897
  • 1,065
  • Sorry, I meant ostream which is what I used in the actual question and text. I have amended the code. – jackj Feb 08 '11 at 06:27
  • To whoever downvoted: can you explain what the problem is with this answer? – templatetypedef Feb 08 '11 at 18:15
  • It's worth mentioning that it's illegal to use the value of an object of incomplete type, so an `` which doesn't include `` declares an absolutely useless `std::cout`. I doubt many library implementers ever tried to do that to their customers. – Potatoswatter Aug 05 '11 at 06:11
5

iostream explicitly includes istream and ostream (C++0x requires this, and the gnu libstdc++ version does this), so ostream is technically unnecessary

for future reference:

fstream contains the declaration for fstream (file streams),

sstream contains the declaration for stringstream (string streams)

iostream declares the standard i/o facilities (e.g. cin, cout, ...)

iosfwd is the standard header that forward-declares the major types.

Foo Bah
  • 25,660
  • 5
  • 55
  • 79
  • @Foo Bah- Can you confirm that includes these two headers? The spec seems to be mute on this point. – templatetypedef Feb 08 '11 at 06:32
  • @templatetypedef gnu makes the claim here: http://gcc.gnu.org/onlinedocs/libstdc++/manual/bk01pt11ch24.html – Foo Bah Feb 08 '11 at 06:36
  • 2
    @Foo Bah- This is true for the GNU implementation, but is it guaranteed to be this way? That is, could someone make a conformant compiler that didn't do it like this? – templatetypedef Feb 08 '11 at 06:37
  • @templatetypedef `iostream` declares `cout`, and `cout` is an object of type `ostream`, which is declared in `ostream` header – Foo Bah Feb 08 '11 at 06:39
  • @Foo Bah- `` actually just contains `extern` declarations for these types, and with the forward declarations in `` it seems like it could get by without those headers. – templatetypedef Feb 08 '11 at 06:40
  • 2
    @templatetypedef actually had to dig this out :/ yes according to C++98, you technically could define iostream without istream, but that would involve `` including ``. C++0x explicitly requires `` to include `` and ``. Technically the best way to be compliant with old and new standards is to have iostream include istream and ostream – Foo Bah Feb 08 '11 at 06:49
  • @Foo Bah- Thanks for finding that! I know this is a minute point, but it actually could influence the way in which I write C++ code. – templatetypedef Feb 08 '11 at 06:50
  • @templatetypedef http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3092.pdf -- page 975 – Foo Bah Feb 08 '11 at 06:51
  • If `` was not guaranteed to define the streams, then the classic `#include / int main() { std::cout << "Hello world!\n"; }` is flawed as it needs implementation... bit hard to believe that's true on any real compiler, whether the Standard's explicit or not. – Tony Delroy Feb 08 '11 at 09:00
  • @Tony declares cout. that wasnt templatetypedef's question. his question was that the declaration was available in both and – Foo Bah Feb 08 '11 at 14:57