You need to #include <ostream>
. The reason it doesn't work without that is because that's the header that actually defines std::ostream
and all those useful operator<<
functions.
The reason it doesn't freak out and complain about "no definition for std::ostream
" (or other the <<
operators) is because of forward declaration. If you forward declare a type, you can use it as a pointer or reference (so long as you don't try to further access it). You can do some things with an incomplete type.
Those other headers you were including were likely forward declaring std::ostream
, but never giving a full definition for it and all the <<
operators. At least on your Ubuntu system. On the other systems, it's possible the other headers could have included <ostream>
or at least provided some of the definitions that <ostream>
does. Your operator<<
was probably the only one the compiler was seeing (because you hadn't included <ostream>
), and since it was the only one the compiler knew of, it was trying to use it for everything.
In short, when working on cross platform stuff, one should be pedantic about including exactly what's necessary (and not relying on other headers to include things that aren't related to them).