Why is it that wcout << ""; is OK but wcout << string(); is not?
c++, encoding, iostream, string
Solution
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`.
Problem
``` #include <iostream> #include <string> using namespace std; int main() { wcout << L"Hello"; // OK. wcout << wstring(L"Hello"); // OK. wcout << "Hello"; // OK. Why? wcout << string("Hello"); // Error. Why? } ``` Why does `std::wcout` accept a narrow string literal as its argument but doesn't accept a narrow string object?