1

この質問を重複させて申し訳ありませんが、そこにコメントするのに必要な評判がなく、そこにある答えは私にとって説得力がありません.

#include<iostream>

class my_ostream : public std::ostream
{
    public:
    std::string prefix;

    my_ostream():prefix("*"){}

    my_ostream& operator<<(const std::string &s){
        std::cout << this->prefix << s;
        return *this;
    }
};

int main(){
  my_ostream s;
  std::string str("text");
  s << str << std::endl;
}

ここで私は得る:

's.my_ostream::operator<<(((const std::string&)((const std::string*)(& str)))) << std::endl' の 'operator<<' に一致しません</p>

理由がわかりません。ostream で機能する場合は、my_ostream でも機能するはずです。このプログラムは動作します:

#include <iostream>
using namespace std;

class a{};
class b:public a{};
class c:public b{};

void f(a){cout << 'a' << endl;}
void f(b){cout << 'b' << endl;}
void f(b, a){cout << "b, a" << endl;}
void f(c){cout << 'c' << endl;}
void f(c, int){cout << "c, int" << endl;}

void f(a*){cout << "pa" << endl;}
void f(b*){cout << "pb" << endl;}
void f(b*, a*){cout << "pb, pa" << endl;}
void f(c*){cout << "pc" << endl;}
void f(c*, int){cout << "pc, int" << endl;}

int main(){
  a ao; b bo; c co;
  f(ao); f(bo); f(co);
  f(co, ao);
  a *pa=new(a); b *pb=new(b); c *pc=new(c);
  f(pa); f(pb); f(pc);
  f(pc, pa);
  return 0;}

以下を出力します。

a
b
c
b, a
pa
pb
pc
pb, pa

したがって、単純なオーバーロードではこのエラーは説明できません。また、ここではテンプレートを紹介しません。そのため、未定のテンプレート タイプ パラメータは重要ではありません。iostream のコードを読むのは非常に難しいことがわかっているので、ご意見をいただければ幸いです。

4

2 に答える 2

4

単純なオーバーロードでこのエラーが説明されます。実際、std::cout問題を複雑にするだけです。以下も機能しません。

int main(){
  my_ostream s;
  s << 1;
}

問題は、operator <<オーバーロードが事実上、基本クラスに定義されているすべてのオーバーロードを隠していることです。

大雑把に言えば、C++ はスコープ解決の後にオーバーロード解決を行います。したがって、C++ はまずoperator <<、クラスのスコープに が定義されているかどうかを確認します。がある!そのため、より一般的な関数の検索をすぐに停止し、オーバーロードの解決のために既に見つかった関数のみを考慮します。残念ながら、オーバーロードが 1 つしかないstd::stringため、呼び出しは失敗します。

operator <<これは、メンバー関数ではなくフリー関数として定義するだけで修正できます。

my_ostream& operator<<(my_ostream& out, const std::string &s) {
    std::cout << out.prefix << s;
    return out;
}

…しかしもちろん、クラス定義が単に意味的に間違っているため、これは問題の一部を修正するだけです。このように IO ストリームをサブクラス化することはできません。ここで私の知識は失敗しますが、あなたが望むことをするためには、ストリームバッファのuflow機能をオーバーライドする必要があると思います.

于 2012-11-30T09:37:09.707 に答える