#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?
}
为什么std::wcout
接受一个窄字符串文字作为它的参数,但不接受一个窄字符串对象?
这是通过在§C ++ 11标准,其中,以下两个重载操作符(等等)指定的27.7.3.6.4规定:
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
);
明确与最后超载交易char
为基础的C字符串。 这意味着,即使在的实例basic_ostream<>
与参数类模板wchar_t
会有一个超载将处理窄char
的字符串。
此外,每§27.7.3.6.4 / 5:
填充,如在22.4.2.2.2描述来确定。 从S开始的n个字符使用out.widen(27.5.5.3)加宽。 加宽字符和任何所需的填充插入出来 。 呼叫宽度(0)。
在另一方面,声明
wcout << string("Hello");
不编译,因为
string
没有一个隐式转换
const char*
,并且因为没有超负荷
operator <<
将插入一个
string
一个字符类型内置到了不同的底层字符类型的输出流。
在标准条件(见第21.4.8.9),这里是重载的定义如何operator <<
看起来像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
);
正如你所看到的,在同一模板参数charT
用于实例都basic_ostream
和basic_string
。
对于第一个,我猜这个重载使用:
template< class CharT, class Traits >
basic_ostream<CharT,Traits>& operator<<( basic_ostream<CharT,Traits>& os,
const char* s );
其中wstream
本质上是一个basic_ostream<wchar_t>
。
对于为什么string("Hello")
不起作用,它只是因为没有转换,从string
到wstring
,也没有过载operator<<
提供。