Edit: I can't seem to find a compiler where it doesn't work. |
You might be right: now that I looked at the actual chains of includes that lead from iostream to string in a few libraries, it may be true that it's a requirement: two of the member functions of
std::cout
(
imbue()
and
getloc()
) return
std::locale
objects by value, so to compile it, the compiler must be able to see the entire class definition of
std::locale
.
std::locale::name()
returns
std::string
by value, so to compile
std::locale
, the compiler must see the class definition (but not the non-member operators such as I/O) of
std::string
.
Just to appreciate the complexity behind the scenes, in dinkumware-derived libraries (IBM, and I believe Microsoft, too), <iostream> includes <istream>, which includes <ostream> which includes <ios>, which includes <xlocnum>, which includes <streambuf>, which includes <xiosbase>, which includes xlocale>, which includes <xlocinfo>, which includes <xstring> (technically, because their internal class _Locinfo has three private data members of type std::string. the chain didn't even reach locale::name())
in stlport-derived libraries (used by Sun), even quicker, <iostream> includes <stl/_istream.h> which includes <stl/_ios.h>, which includes <stl/_ios_base.h> which includes <stl/_string.h> because their
std::ios_base
has a private data member of type
std::string
.
In the best-designed (in my opinion) implementation, libc++, <iostream> includes <ios>, which includes <__locale>, which includes <string> for the sake of std::locale::name() only, no surprise private members.
Still, although it's an interesting bit of trivia, do include the headers for the thigns you use.