wostream,wistream?

I'm having some trouble understanding what these are, along with wcin, wcout, wcerr, wclog, wistringstream, and so on. Could someone please enlighten me?
They are similar to cin, cout, cerr, clog, istringstream but work with wchar_t instead of char. wchar_t is called a wide character. wchar_t is bigger than a char so it can hold any more different characters, like Chinese characters and such.
Last edited on
But as they are they do nothing useful. (I/O simply passes through widen()/narrow().) You must be sure to imbue them with the proper locale and facets to make them do what you want, which is a whole can of worms in itself.
Okay. Got it. One question. (I am about to sound so stupid.) Why not make an abstract base class (I don't know, aostream?) which contains a pure virtual operator<< from which both ostream and wostream are derived, so overloading operator<< for aostream would do so for ostream and wostream? Normally, one would need to separately overload for ostream and wostream, if I remember correctly.
Last edited on
Both member and non-member operator<<'s of std::ostream/std::wostream already call virtual functions, they don't have to be virtual themselves.

As for overloading, while you can overload them separately, it usually makes more sense to just provide an operator<< for basic_ostream<>.
Okay. Thanks. One more quick question. (I know I'm getting really annoying.) Why can't I find any documentation on wcout, wcin, wostream, wistringstream, or anything related to the wide char versions of the basic I/O in this site's reference?
They are the same as their narrow counterparts, but with wchar_t.

For example, if you examine the definition of the type std::string, you'll see it is a typedef of a std::basic_string<> template class. Well, std::wstring is the exact same thing only using a different type in the template. This therefore means that everything works the same because it is the same exact code.
Also, you seem to have some confusion about the structure of the I/O streams.

The levels of abstraction are carefully decoupled so that you can do neat stuff easily -- the trick is that it is not so obvious and you really need a good reference to understand it well.

The highest-level is the operator overloads, which work polymorphically. Once you define the insertion and extraction operators for a specific type over a stream, you can use them with any stream.

1
2
3
4
5
6
7
8
9
10
11
12
13
struct point
  {
  double x, y;
  ...  
  };

// stream insertion operator -- works with ANY stream for a 'point'
template <typename CharT, typename Traits>
basic_iostream <CharT, Traits> &
operator << ( basic_iostream <CharT, Traits> & outs, point& p )
  {
  return outs << "(point " << x << " " << y << ")";
  };

Hope this helps.
Topic archived. No new replies allowed.