开发者

Passing a child of std::ostream to a library that wants std::ostream *

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);
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜