我如何超载<< 操作员?

发布于 2024-07-27 04:41:14 字数 513 浏览 3 评论 0 原文

我打算在调用 m_logger<<"hello"<<"world" 时调用一个函数。 m_logger 是 ofstream 类型。

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

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

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

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

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

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

I intend to call a function whenever m_logger<<"hello"<<"world" is called. m_logger is of type ofstream.

So i decide to overload << with following signature

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

However the vc compiler gives following error:

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

Is there anyother way to achieve this, my objective is to divert all the write operation to ofstream object to different function?

Creating an object of my own calss works for me, however how can i make it work like normal ofstream object which typecasts all system defined types into strings or char*. i know one approach would be to overload the operator for each and every type but is there a cleaner approach

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

生生漫 2024-08-03 04:41:14

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

"overload" isn't "override". You can overload a function or operator for arguments of different types; you cannot override an existing function or operator with your own implementation (aside from overriding virtual functions, which is obviously very different). The only exceptions are operator new and operator delete, where it's possible to override built-in ones.

日裸衫吸 2024-08-03 04:41:14

问题是 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 *

The problem is that ofstream is already overloaded this way. If you make mlogger of a new type holding an ofstream, then you can do this:

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";

Also, you should definitely use a const string& (as I did in this example) rather than a C-style string. If you really need it to be C-style, at least use const char *.

零度℉ 2024-08-03 04:41:14

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

You could change the type of the m_logger object.

素罗衫 2024-08-03 04:41:14

根据您想要重载运算符 << 的原因,正确的解决方案是

  • 使用 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。

Depending on why you want to overload operator<<, the correct solution is either

  • to use another type than a descendant of ostream as target stream; in that case you have to write all operators << yourself, but you can get help from templates if you want to forward by default.

Like this:

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

and you'll see that manipulators don't match the template, so you'll also need something like:

myStream& operator<<(myStream& fl, std::ostream& (*fn)(std::ostream&))
{
    s.getStream() << fn;
}
  • to write your own streambuf which delegates I/O to a std::filebuf (this is a little too complicated to give an example here, search the web -- filtering streambuf is a good keyword for that. If I remember correctly, boost has an helper library for that which may be useful. Note that in this case, you'll probably end up by using another type that an fstream, but which will descend from ostream.
心欲静而疯不止 2024-08-03 04:41:14

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

What you should do is make a class and then define operator<<. An operator overload must contain at least one user-defined type. Similarly, you can't write a new operator+(int, int).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文