#include
#include
using namespace std;
int main()
{
wcout << L\"Hello\"; // OK.
wcout << wstring(L\"He
For the first one, I'm guessing this overload is used:
template< class CharT, class Traits >
basic_ostream<CharT,Traits>& operator<<( basic_ostream<CharT,Traits>& os,
const char* s );
Where wstream is essentially a basic_ostream<wchar_t>.
For why string("Hello") doesn't work, it's simply because there is no conversion from string to wstring, nor an overload of operator<< provided.
This is dictated by § 27.7.3.6.4 of the C++11 Standard, where the following two overloaded operators (among others) are specified:
template<class charT, class traits>
basic_ostream<charT,traits>& operator<<(
basic_ostream<charT,traits>& out,
const charT* s
);
template<class charT, class traits>
basic_ostream<charT,traits>& operator<<(
basic_ostream<charT,traits>& out,
const char* s
);
The last overload deals explicitly with char-based C-strings. This means that even for instantiations of the basic_ostream<> class template with the argument wchar_t there will be one overload which will deal with narrow char strings.
Moreover, per § 27.7.3.6.4/5:
Padding is determined as described in 22.4.2.2.2. The n characters starting at s are widened using out.widen (27.5.5.3). The widened characters and any required padding are inserted into out. Calls width(0).
wcout << string("Hello"); does not compile because string does not have an implicit conversion to const char*, and because there is no overload of operator << that would insert a string built with one character type into an output stream with a different underlying character type.
In Standard terms (see § 21.4.8.9), here is how the definition of the overloaded operator << looks like for std::string:
template<class charT, class traits, class Allocator>
basic_ostream<charT, traits>& operator<<(
basic_ostream<charT, traits>& os,
const basic_string<charT,traits,Allocator>& str
);
As you can see, the same template parameter charT is used to instantiate both basic_ostream and basic_string.