【问题标题】:Why is it that wcout << ""; is OK but wcout << string(); is not?为什么是 wcout << "";可以,但是 wcout << string();不是?
【发布时间】:2013-01-19 18:11:33
【问题描述】:
#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 接受窄字符串文字作为其参数,但不接受窄字符串对象?

【问题讨论】:

  • error: no match for 'operator&lt;&lt;' in 'std::wcout &lt;&lt; std::basic_string&lt;char&gt;(((const char*)"Hello"), (*(const std::allocator&lt;char&gt;*)(&amp; std::allocator&lt;char&gt;())))'?
  • +1 我也对这个 IOStream 的怪异感到困惑。
  • 为什么?因为石冷是这么说的!这就是为什么

标签: string encoding iostream c++


【解决方案1】:

这是由 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&lt;&gt; 类模板的实例化,参数为 wchar_t,也会有一个重载来处理窄的 char 字符串。

此外,根据 § 27.7.3.6.4/5:

填充如 22.4.2.2.2 中所述确定。 从 s 开始的 n 个字符使用 out.widen (27.5.5.3) 加宽。将加宽的字符和任何所需的填充插入到 out 中。调用 width(0)。


另一方面,语句wcout &lt;&lt; string("Hello"); 无法编译,因为string 没有到const char* 的隐式转换,并且因为operator &lt;&lt; 没有重载会插入使用一种字符类型构建的string到具有不同基础字符类型的输出流中。

在标准术语中(参见第 21.4.8.9 节),以下是重载 operator &lt;&lt; 的定义对于 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_ostreambasic_string

【讨论】:

    【解决方案2】:

    对于第一个,我猜是this overload

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

    wstream 本质上是 basic_ostream&lt;wchar_t&gt;

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

    【讨论】:

    • 呵呵,好笑。我假设第二个参数只是const CharT *
    • 只是因为没有从wstring到string的转换是错字吗?应该是只是因为没有从string到wstring的转换
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-03-06
    • 1970-01-01
    • 2012-12-03
    • 1970-01-01
    • 2015-11-27
    • 2013-09-11
    • 2011-12-18
    相关资源
    最近更新 更多