views:

225

answers:

5

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

+2  A: 

You could change the type of the m_logger object.

Martin York
+5  A: 

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

Pavel Minaev
+1  A: 

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).

rlbond
+2  A: 

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.
AProgrammer
+2  A: 

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 *.

Zifre
this worked for me, however there is one more problem. i need mlogger to work just like ofstream object. this method fails if i try to write integer or types other than the char* eg: mlogger<<3; would i have to overload each and every known type? for this to work?
Kazoom
You could use a template in that case.
Zifre