1. Es ist nicht iostreams sind nicht entwickelt worden um mit temporären Objekten zu arbeiten.
2. Das Problem ist, dass dein temporärer iostream ein rvalue ist, der aus der Funktion zurückkommt. Alle temporären Objekte sind IMHO rvalues und damit const!
Es gibt zwei überladene Funktionen für operator<<, die hier nun ins Spiel kommen. Eine member Funktion die einen void* nimmt und eine non-member Funktion, die einen wchar_t* annimmt.
Deine Objekt ist aber ein rvalue (const), also ist dies kein Kandidat für die non-member Funktion (siehe Überladungsregeln). Allerdings hindert nichts daran das der const wchar_t* implizit auf const void* für die member Funktion konvertiert wird.
Also wird es als void* behandelt.
Wenn Du also brutal den rvalue wegcastest, funktioniert es wie erwartet:
template<typename T>
T & make_lvalue(T const & x)
{
return const_cast<T &>(x);
}
make_lvalue(say()) << L"Hello World!";
Unterschied zum VC6?
Der VC6 und sein STL und Template Implementierung waren falsch und buggy.
Dein Code hätte unter VC6 schon nicht gehen dürfen!
Anmerkung: Also 100% sicher bin ich mir nicht.
Aber evtl. gibt es ja nochmehr Gurus hier, die den Standard inhaliert haben.