使用boost::iostreams::tee_device?

7

你能帮我一下吗?

我正在尝试做类似于以下的事情:

#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());

但在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

有人成功实现了这个吗?我知道我可以自己创建一个类来完成它,但我想知道我做错了什么。

谢谢

3个回答

12
您正在使用构造函数转发版本io::stream,它会自行构建一个tee-stream并将所有参数转发给它。C++03在将参数转发给函数时只具有有限的能力(所需重载数量很容易呈指数级增长)。它(io::stream)有以下限制:

这些成员中的每一个都构造了一个流实例,并将其与从给定参数列表构造的设备T关联起来。涉及的T构造函数必须通过值或const引用接收所有参数。

好吧,但tee_device构造函数说:

基于给定的Sinks对构造一个tee_device实例。如果相应的模板参数是流或流缓冲区类型,则每个函数参数均为非const引用,否则为const引用。

当然这不起作用。 io::stream提供了另一个以T为第一个参数的构造函数。这在这里起作用(至少编译通过。然而,断言失败了。我没有使用过boost::iostreams,所以无法提供帮助)。
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());

编辑:在调用flush()或流式传输<< std::flush之后,断言通过。

哇...文档中没有看到这个。太棒了,非常感谢! - rlbond
虽然有一种更简洁的解决方案,即使用std::ref,但对问题的分析是正确的。 - undefined

2
也许您需要像这样设置它:
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);

0
使用std::ref来传递不可复制的接收器。
Tee my_split(std::ref(ss1), std::ref(ss2));

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接