0

問題:

#include <iostream>
#include <sstream>

class MyClass : private std::ostream
{
public :
    MyClass() : std::ostream(&mBuffer) { }

    using std::operator<<; 


private:
    std::stringbuf mBuffer;
};

// In main function, for example
MyClass c;
c << 'A' << "Hello, World!";  // Works
c << "Hello, World!" << 'A';  // ERROR

エラー(MS Visual Studio 2010)はエラーC2666です:'std :: basic_ostream <_Elem、_Traits> :: operator <<':5つのオーバーロードは同様の変換を行います

私は何を間違っているのですか、それともこれは別のMS Visual Studioのバグですか?

回避策: 次のメンバーメソッドを追加することは機能しているようですが、根本的な原因についての洞察が必要です。

MyClass& operator<<(const char* str) { 
        std::ostream& os = *this;
        os << str;
        return *this; 
    }

背景: VS2010は(とりわけ)std :: ostreamのパブリック継承をサポートしていないため、MySql++はVisualStudio 2010(メーリングリストを参照)でコンパイルされません。回避策として、私はプライベート継承を試みています。これは、構成よりもハッキングが少ないためです。MyClass&operator <<(const char * str){std :: ostream&os = * this; os << str; *thisを返します。}

完全なエラーメッセージ

1>d:\repo\test\test\main.cpp(30): error C2666: 'std::basic_ostream<_Elem,_Traits>::operator <<' : 5 overloads have similar conversions
1>          with
1>          [
1>              _Elem=char,
1>              _Traits=std::char_traits<char>
1>          ]
1>          d:\program files (x86)\microsoft visual studio 10.0\vc\include\ostream(206): could be 'std::basic_ostream<_Elem,_Traits> &std::basic_ostream<_Elem,_Traits>::operator <<(std::_Bool)'
1>          with
1>          [
1>              _Elem=char,
1>              _Traits=std::char_traits<char>
1>          ]
1>          d:\program files (x86)\microsoft visual studio 10.0\vc\include\ostream(467): or       'std::basic_ostream<_Elem,_Traits> &std::basic_ostream<_Elem,_Traits>::operator <<(const void *)'
1>          with
1>          [
1>              _Elem=char,
1>              _Traits=std::char_traits<char>
1>          ]
1>          d:\program files (x86)\microsoft visual studio 10.0\vc\include\ostream(851): or       'std::basic_ostream<_Elem,_Traits> &std::operator <<<char,std::char_traits<char>>(std::basic_ostream<_Elem,_Traits> &,const _Elem *)' [found using argument-dependent lookup]
1>          with
1>          [
1>              _Elem=char,
1>              _Traits=std::char_traits<char>
1>          ]
1>          d:\program files (x86)\microsoft visual studio 10.0\vc\include\ostream(764): or       'std::basic_ostream<_Elem,_Traits> &std::operator <<<std::char_traits<char>>(std::basic_ostream<_Elem,_Traits> &,const char *)' [found using argument-dependent lookup]
1>          with
1>          [
1>              _Elem=char,
1>              _Traits=std::char_traits<char>
1>          ]
1>          d:\program files (x86)\microsoft visual studio 10.0\vc\include\ostream(679): or       'std::basic_ostream<_Elem,_Traits> &std::operator <<<char,std::char_traits<char>>(std::basic_ostream<_Elem,_Traits> &,const char *)' [found using argument-dependent lookup]
1>          with
1>          [
1>              _Elem=char,
1>              _Traits=std::char_traits<char>
1>          ]
1>          while trying to match the argument list '(MyClass, const char [14])'
4

3 に答える 3

3

operator<<The Right Thing(TM)を実行するように転送します。

class MyClass : private std::ostream
{
public :
    MyClass() : std::ostream(&mBuffer) { }

    template <typename T>
    MyClass& operator<<(T&& t)
    {
        static_cast<std::ostream&>(*this) << std::forward<T>(t);
        return *this;
    }

private:
    std::stringbuf mBuffer;
};

実際、一部のストリーム演算子は、のメンバー関数としてではなく、(フレンド)フリー関数として宣言されていますstd::ostream。宣言を使用しても、それらはインポートされません。

于 2012-09-13T12:19:52.617 に答える
1

これは、ストリームインサーターの定義方法に少し癖があるためです。一部はostream;のメンバーです。これらは、using宣言によって取得されるものです。一部は無料の関数です。それらはstream&(まあ、正式にはbasic_ostream<charT>&)を取り、あなたのタイプでは機能しません。そのためc << 'a'、大丈夫(のインサーターcharはのメンバーですostream)、そうではありc << "Hello, world!"ません(のインサーターchar*はメンバー関数ではありません。stream&左側にが必要です)。また、では、部分c << 'a' << "Hello, world!"式の戻り型はであるため、次のインサーターはではなくを参照するため、その時点で問題ありません。c << 'a'ostream&ostream&MyClass

回避策は、の問題を回避しますが、、、またはユーザー定義char*タイプなどの他のタイプには役立ちません。std::stringstd::complex

正解は、の代わりに使用できる型を作成する場合はostreamostreamパブリック継承から始めて、適切なオーバーライドを実装する必要があるということです。

于 2012-09-13T12:12:41.367 に答える
0

明確にするために、あなたは意味しました

using std::ostream::operator<<;

それよりも

using std::operator<<;
于 2012-09-13T04:35:54.987 に答える