开发者

Doubling a stream

I'm using t开发者_Go百科he cerr stream for my error output, but I also wanted to save any of this error output in a stringstream in memory.

I'm looking to turn this:

stringstream errorString;
cerr << " Something went wrong ";
errorString << " Something went wrong ";

Into

myErr << " Something went wrong ";

Where myErr is an instance of a class that stores this in a stringstream and also outputs to cerr.

Thanks for any help.


You could create the type of your myErr class like this:

class stream_fork
{
    std::ostream& _a;
    std::ostream& _b;

public:
    stream_fork( std::ostream& a, std::ostream& b)
        :   _a( a ),
            _b( b )
    {
    }

    template<typename T>
    stream_fork& operator<<( const T& obj )
    {
        _a << obj;
        _b << obj;
        return *this;
    }

    // This lets std::endl work, too!
    stream_fork& operator<<( std::ostream& manip_func( std::ostream& ) )
    {
        _a << manip_func;
        _b << manip_func;
        return *this;
    }
};

Usage:

stream_fork myErr( std::cerr, errorString );
myErr << "Error Message" << std::endl;


You can use Boost.IOStreams.

#include <boost/iostreams/tee.hpp>
#include <boost/iostreams/stream.hpp>
#include <iostream>
#include <sstream>

namespace io = boost::iostreams;

int main() {
    std::stringstream ss;
    io::tee_device<decltype(ss), decltype(std::cerr)> sink(ss, std::cerr);
    io::stream<decltype(sink)> stream(sink);
    stream << "foo" << std::endl;
    std::cout << ss.str().length() << std::endl;
    return 0;
}


Override operator<< in your MyErr class

MyErr& operator<< ( MyErr& myErr, std::string message)
{
    cerr << message;
    errorString << message; //Where errorString is a member of the MyErr class

    return myErr;
}

Then where you want to log the error:

int main()
{
    MyErr myErr;
    myErr << " Something went wrong. ";

    return 0;
}

You might want to make MyErr a singleton class so that everything written to errorString is in one place.


Use Boost tee.


You need to subclass streambuf and declare myErr as an ostream that uses your subclass. Make the input functions do nothing and then have the output functions copy out to whatever streams you need.

I had a class that did something similar 12 years ago, but have lost track of it. I haven't been able to find a good example, but the docs for streambuf could be a starting point. Focus on the protected output functions.

0

上一篇:

下一篇:

精彩评论

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

最新问答

问答排行榜