17
#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引数としてナロー文字列リテラルを受け入れるのに、ナロー文字列オブジェクトを受け入れないのはなぜですか?

4

2 に答える 2

8

これは、C++11 標準の § 27.7.3.6.4 で規定されており、次の 2 つのオーバーロードされた演算子が (とりわけ) 指定されています。

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文字列を処理する 1 つのオーバーロードがあることを意味します。

さらに、§ 27.7.3.6.4/5 によると:

パディングは、22.4.2.2.2 で説明されているように決定されます。s で始まる n 文字は、out.widen (27.5.5.3) を使用して拡張されます。拡張された文字と必要なパディングが out に挿入されます。width(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

于 2013-02-04T22:49:21.863 に答える
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")が機能しない理由は、単に からstringへの変換がなくwstring、提供されたのオーバーロードがないためoperator<<です。

于 2013-02-04T22:47:58.907 に答える