2012-11-29 77 views
1

我很抱歉我复制了this question,但我没有评论的声望以及那里没有令人信服的答案。过载后'std :: endl'的'operator <<'不匹配

#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 ::运算敌不过 '操作< <' < <(((常量的std :: 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代码证明是非常困难的,所以我非常感谢任何见解。

+0

事实证明'std :: ostream s;'也不起作用,所以这是相当复杂和难以理解的。 –

+0

互联网说'cout'是'ostream'类型的,但是。任何人都可以解开这个节点? :) –

回答

2

简单重载确实解释此错误。实际上,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; 
} 

...但当然,这只是修复了一些你的问题,因为你的类定义仅仅是语义错误的;你不能像这样继承IO流。在这里,我的知识失败,但我认为为了做你想做的事情,你应该覆盖流缓冲区的功能uflow

+1

谢谢你的回答。我不能相信C++不会重载继承的函数(它不会,我验证过),我不相信我不知道它。很高兴知道ostream不会被分类。将'operator <<'从my_ostream中取出后,程序编译完成,但是当它到达'std :: endl'时,它会抛出一个'std :: bad_cast'。请告诉我为什么会发生这种情况。 uflow似乎只为文件定义,'filebuf :: uflow'。也许我应该重写'std :: streambuf :: sputc'并从重写函数中调用它? –

相关问题