30

I started learning C++ and I read a book which writes that I must use the <string> header file because the string type is not built directly into the compiler. If I use the <iostream> I can use the string type.

Do I have to include the <string> header when I want to use the string type if I included the <iostream> header? Why? Is there some difference?

kluka
  • 271
  • 3
  • 16
KOB
  • 1,156
  • 1
  • 16
  • 33

2 Answers2

35

Yes, you have to include what you use. It's not mandated that standard headers include one another (with a few exceptions IIRC). It might work now, but might fail on a different compiler.

In your case, apparently <iostream> includes <string>, directly or indirectly, but don't rely on it.

Luchian Grigore
  • 253,575
  • 64
  • 457
  • 625
  • It's probably a forward declaration of string ( includes which includes ing gcc's implementation). I think that's standard behaviour (would have to check the standard though), so I believe he can rely on it when he doesn't need the full type. – Aleph May 12 '13 at 10:00
  • @AnotherTest "I can use the string type" - tells me he needs the full type. If he doesn't, a forward-declaration would do, yes. – Luchian Grigore May 12 '13 at 10:03
  • 27.5.1 states that must include . That only needs `char_traits`, so I'm not sure whether a compiler must also forward declare `string`. I still doubt that any implementation of iostream includes the entire string header. – Aleph May 12 '13 at 10:16
9

Do I have to include the <string> header when I want to use the string type if I included the <iostream> header?

Yes, you have to. You cannot rely on relevant headers (e.g. <string>) being #included indirectly through other headers (e.g. <iostream>), although this might be the case on some implementations.

And even when this may seem to work, it could lead to troubles if not all of the relevant overloads of some operators are imported, or if a class is forward-declared in a header you #include, but information on that class being derived from some other class is only contained in a header that does not get #included.

See, for instance, this Q&A on StackOverflow for an example of such situations.

Community
  • 1
  • 1
Andy Prowl
  • 124,023
  • 23
  • 387
  • 451
  • [ios_base::getloc](http://en.cppreference.com/w/cpp/io/ios_base/getloc) returns a `std::locale` by value, and [locale::name](http://en.cppreference.com/w/cpp/locale/locale/name) returns `std::string` by value, so `#include ` is actually required to fully define `std::string`. Only the non-members from `` are optional. – Cubbi Sep 14 '13 at 15:28
  • very good point. I just ran into an issue where some library code we are using relied on this and when we upgraded from a very old OS/compiler to a newer version, compilation broke for "no apparent reason" other than this. – user320781 Dec 15 '14 at 18:00