#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?
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
.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With