0

我打算每当调用m_logger<<"hello"<<"world"时调用一个函数。 m_logger是类型的流。如何重载<<运算符?

所以我决定超载< <具有以下签名

friend ofstream& operator<<(ofstream &stream,char *str); 

然而,VC编译器提供了以下错误:

error C2666: 'operator <<' : 6 overloads have similar conversions

是否有任何其它的方式来实现这一目标,我的目标是为了转移所有将流操作对象转换为不同的函数?

创建我自己的calss对象为我工作,但是我怎样才能使它像普通的ofstream对象那样将所有系统定义的类型转换为字符串或char *。我知道一种方法是为每种类型的操作员超载,但是有更清洁的方法

+0

@Kazoom:我编辑了我的答案,以显示将任何内容传递给内部'ofstream'(它使用函数模板)的通用方法。 – Zifre 2009-07-16 13:25:45

回答

2

问题是ofstream已经超载这种方式。如果您mlogger新型持有ofstream的,那么你可以这样做:

class mlogger_t { 
public: 
    ofstream stream; 
    ... 
} 

mlogger_t& operator<<(mlogger_t& stream, const string& str) { 
    stream.stream << str; 
    ... 
} 

//EDIT: here is how to make this work for other types too using templates: 
template<typename T> mlogger_t& operator<<(mlogger_t& stream, T val) { 
    stream.stream << val; 
} 

... 

mlogger_t mlogger; 

mlogger << "foo"; 

而且,你一定要使用const string&(正如我在这个例子中所做的那样),而不是C风格的字符串。如果你真的需要它是C风格,至少使用const char *

+0

这对我有效,但还有一个问题。我需要mlogger像流媒体一样工作。如果我尝试写入除char *以外的整数或类型,则此方法失败。例如:mlogger << 3;我是否必须重载每个已知类型?为了这个工作? – Kazoom 2009-07-15 20:08:00

+0

您可以在这种情况下使用模板。 – Zifre 2009-07-16 00:09:06

2

您可以更改m_logger对象的类型。

5

“过载”不是“覆盖”。您可以为不同类型的参数重载函数或运算符;你不能用你自己的实现覆盖现有的函数或操作符(除了重写虚拟函数,这显然是非常不同的)。唯一的例外是operator newoperator delete,其中可以覆盖内置的。

1

你应该做的是做一个班级,然后定义operator<<。运算符重载必须至少包含一个用户定义的类型。同样,你不能写一个新的operator+(int, int)

2

取决于你为什么要重载operator < <,正确的解决方法是,

  • 使用另一种类型比的ostream作为目标流的后裔;在这种情况下,您必须自己编写所有运营商< <,但如果您希望默认转发,则可以从模板获得帮助。

像这样:

template <typename T> 
myStream& operator<<(myStream& s, T const& v) 
{ 
    s.getStream() << v; 
} 

,你会看到,操纵不匹配模板,所以你也需要类似:

myStream& operator<<(myStream& fl, std::ostream& (*fn)(std::ostream&)) 
{ 
    s.getStream() << fn; 
} 
  • 写你自己的streambuf委托I/O到一个std :: filebuf(这有点太复杂了,不能在这里给出一个例子,搜索网页 - 过滤streambuf是一个很好的关键字。如果我没有记错,boost已经可能有用的辅助库。请注意,在这种情况下,您最终可能会使用另一种类型的fstream,但会从ostream中下载。