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).
On the other hand, the statement
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
.
error: no match for 'operator<<' in 'std::wcout << std::basic_string<char>(((const char*)"Hello"), (*(const std::allocator<char>*)(& std::allocator<char>())))'
? – Brittanybritte