I have a class (for logging) which derives from std::ostream. Stripped down, it looks like this:
class bsgs : public std::ostream {
public:
bsgs(const std::string& msg = "") {
// some setup work
}
~bsgs() {
// some cleanup work
}
template<typename T>
bsgs& operator<<(const T& rhs) {
os << rhs;
return *this;
}
private:
std::ostringstream os;
};
I wrote this class to do a few particular things I need like delta compression. Unfortunately, it doesn't work. I need to pass it to a third-party library (with source, but fairly large and messy) that provides a "set_out" function to direct its output to a std::ostream. The set_out function prototype is exactly this:
void set_out(std::ostream *out=0, int level=1);
and if I call it as:
set_out(&std::cout, 3);
or
set_out(&std::cerr, 5);
I get exactly the expected behavior. However, if I write:
bsgs logger;
set_out(&logger, 3);
I can see that the logger's constructor and destructor are called as expected but operator<<
is never called. I'm not sure why, and I hope this is a simple question. If I can resolve this problem, I'm all set.
Does anyone know what exactly is going on? The problem seems to be that the library has no clue that I'm passing a pointer to a bsgs
and not a std::ostream
, but fixing the library to accept a wider range of objects than just std::ostream *
looks like it might involve touching 500+ lines of code, which I'd like to avoid.
~~~~~~~~~~~~~~
Edit #1: I'm not sure if it is important, but the library has a virtual set_out() = 0;
function at the top of its class hierarchy, which is implemented (identically, as far as I can see) in different subclasses. If I were writing the library I would have made set_out
a (non-virtual) template function and provided with a specialization for std::ostream, but let users provide whatever they like so long as they define a usable operator<<
. Making this change to the library looks like it will be a solid half a day of editing开发者_运维问答. Maybe there's an easier way?
The library has no clue that you're passing a pointer to a bsgs
- you're not overriding a virtual function, there's no polymorphism involved.
You may find that implementing a streambuf
and replacing a streams associated stream buffer (ostream::rdbuf
) is a more viable solution.
You can always use
std::ostringstream os;
set_out(&os, 3);
When you want to derive from ostream, just create your own implementation of streambuf, which is virtual, and create stream like
std::ostream stream(new myStreamBuf);
set_out(&stream, 3);
精彩评论