我很抱歉我复制了this question,但我没有在那里发表评论所需的声誉,而且答案对我来说并不令人信服。
#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&lt;&lt;(((const std :: string&amp;)((const std :: string *)(&amp; str)))中的'operator&lt;&lt;'不匹配)) &LT;&LT;的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 :(得分: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 :(得分:0)
解决此问题的另一种方法被声明为操作符<<重载。
class my_ostream : public std::ostream
{
public:
std::string prefix;
my_ostream():prefix("*"){}
template <class T>
friend my_ostream& operator<<(my_ostream& my_os, const T& s){
std::cout << my_os.prefix << s;
return my_os;
}
};