为什么说wcout <<“”; 是确定的,但wcout <<字符串();

2019-07-19 06:03发布

#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接受一个窄字符串文字作为它的参数,但不接受一个窄字符串对象?

Answer 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<>与参数类模板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_ostreambasic_string



Answer 2:

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

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")不起作用,它只是因为没有转换,从stringwstring ,也没有过载operator<<提供。



文章来源: Why is it that wcout << “”; is OK but wcout << string(); is not?