0

我打算在任何时候调用一个函数m_logger<<"hello"<<"world"。m_logger 属于流类型。

所以我决定用以下签名重载 <<

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

但是vc编译器给出以下错误:

错误 C2666:“运算符 <<”:6 个重载具有类似的转换

有没有其他方法可以实现这一点,我的目标是将所有写入操作转移到 ofstream 对象到不同的功能?

创建一个我自己的对象对我有用,但是我怎样才能让它像正常的 ofstream 对象一样工作,它将所有系统定义的类型转换为字符串或 char*。我知道一种方法是重载每种类型的运算符,但有没有更简洁的方法

4

5 回答 5

5

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

于 2009-07-15T01:08:46.093 回答
2

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

于 2009-07-15T01:04:07.293 回答
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;
}
  • 编写自己的流缓冲区,将 I/O 委托给 std::filebuf (这有点太复杂,无法在这里举个例子,搜索网络——过滤流缓冲区是一个很好的关键字。如果我没记错的话,boost 有一个可能有用的辅助库。请注意,在这种情况下,您可能最终会使用 fstream 的另一种类型,但它会从 ostream 继承。
于 2009-07-15T12:29:25.930 回答
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 *.

于 2009-07-15T12:54:55.783 回答
1

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

于 2009-07-15T01:16:10.287 回答