Can someone help me?
I am trying to do something like the following:
#include <boost/iostreams/tee.hpp>
#include <boost/iostreams/stream.hpp>
#include <sstream>
#include <cassert>
namespace io = boost::iostreams;
typedef io::stream<io::tee_device<std::stringstream, std::stringstream> > Tee;
std::stringstream ss1, ss2;
Tee my_split(ss1, ss2); // redirects to both streams
my_split << "Testing";
assert(ss1.str() == "Testing" && ss1.str() == ss2.str());
But it won't compile in VC9:
c:\lib\boost_current_version\boost\iostreams\stream.hpp(131) : error C2665: 'boost::iostreams::tee_device<Sink1,Sink2>::tee_device' : none of the 2 overloads could convert all the argument types
Has anyone gotten this to work? I know I could make my own class to do it, but I want to know what I am doing wrong.
Thanks
You use the constructor-forwarding version of io::stream
, which construct a tee-stream itself and forward all arguments to that. C++03 has only limited capabilities when it comes to forwarding arguments to functions (amount of overloads needed easily grow exponentially). It (io::stream
) makes the following restrictions:
Each of these members constructs an instance of stream and associates it with an instance of the Device T constructed from the given lists of arguments. The T constructors involved must take all arguments by value or const reference.
Well, but the tee_device
constructor says
Constructs an instance of tee_device based on the given pair of Sinks. Each function parameter is a non-const reference if the corresponding template argument is a stream or stream buffer type, and a const reference otherwise.
That won't work, of course. io::stream
provides another constructor that takes a T
as first argument. This works here (Compiles, at least. The assertion fails, though. I've not worked with boost::iostreams
so i can't help with that)
namespace io = boost::iostreams;
typedef io::tee_device<std::stringstream, std::stringstream> TeeDevice;
typedef io::stream< TeeDevice > TeeStream;
std::stringstream ss1, ss2;
TeeDevice my_tee(ss1, ss2);
TeeStream my_split(my_tee);
my_split << "Testing";
assert(ss1.str() == "Testing" && ss1.str() == ss2.str());
Edit: After calling flush()
or streaming << std::flush
, the assertion passes.
Probably you need to set it up like this:
typedef io::tee_device<std::stringstream, std::stringstream> Tee;
typedef io::stream<Tee> TeeStream;
std::stringstream ss1, ss2;
Tee my_tee(ss1, ss2);
TeeStream my_split(my_tee);