c++ - 重载后,C++ 与 std::endl的'运算符 <<'不匹配

  显示原文与译文双语对照的内容

对不起,我重复了这个问题,但是我没有必要评论的声誉和对我的答案。


#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:: 运算符 <( ( ( ( const ): string&") 中没有 MATCH的'运算符 <<'( ( 。string*:: ) ( & str ) ) ) <<std::endl"'

我不明白为什么。 如果它适用于 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代码非常困难,所以我很欣赏。

时间: 原作者:

简单重载 解释这里错误。 实际上,std::cout 只是使问题复杂化。 以下操作也不适用:


int main(){


 my_ostream s;


 s <<1;


}



问题在于,实际上你的operator << 重载隐藏了所有为基类定义的重载。

大致来说,C++ 在作用域解析之后进行重载解析。 所以 C++ 首先检查在类的范围中是否定义了一个 operator << 。 这里是所以它停止搜索更多的通用函数,只考虑已经找到过载解析的函数。 唉,对于 std::string,只有一个重载,所以调用失败。

通过定义 operator << 不是成员函数,而是自由函数,可以简单地修复这里问题:


my_ostream& operator<<(my_ostream& out, const std::string &s) {


 std::cout <<out.prefix <<s;


 return out;


}



"。"。但这只修复了一些问题,因为类定义只是语义错误,不能像这样子类。 这里我的知识失败了,但是我想要做的是要重写缓冲区函数的流 uflow

原作者:
...