为什么是wcout<< " ";没问题,但 wcout <<字符串();莫?

Why is it that wcout << ""; is OK but wcout << string(); is not?

本文关键字:lt wcout 字符串 没问题 为什么      更新时间:2023-10-16
#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字符串。这意味着,即使对于具有参数wchar_tbasic_ostream<>类模板的实例化,也将存在一个重载,该重载将处理狭窄的char字符串。

此外,根据§27.7.3.6.4/5:

按照22.4.2.2.2中的说明确定填料从s开始的n个字符使用out.widen(27.5.5.3(进行加宽。加宽的字符和任何所需的填充都插入out中。调用宽度(0(。


另一方面,语句wcout << string("Hello");不编译,因为string没有到const char*的隐式转换,并且因为没有operator <<的重载,该重载将使用一个字符类型构建的string插入到具有不同底层字符类型的输出流中。

在标准术语中(见§21.4.8.9(,以下是std::string:过载operator <<的定义

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_ostreambasic_string

对于第一个,我猜使用了这个重载:

template< class CharT, class Traits >
basic_ostream<CharT,Traits>& operator<<( basic_ostream<CharT,Traits>& os, 
                                         const char* s );

其中CCD_ 16本质上是CCD_。

为什么string("Hello")不起作用,只是因为没有从stringwstring的转换,也没有提供operator<<的过载。