2009-03-22 17 views
7

¿Alguien me puede ayudar?Uso de boost :: iostreams :: tee_device?

estoy tratando de hacer algo como lo siguiente:

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

Pero no se compilará en 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 

Alguien ha conseguido que esto funcione? Sé que podría hacer mi propia clase para hacerlo, pero quiero saber qué estoy haciendo mal.

Gracias

Respuesta

10

Se utiliza el constructor-forwarding version de io::stream, que la construcción de un tee-propia corriente y transmita todos los argumentos a eso. C++ 03 tiene capacidades limitadas cuando se trata de reenviar argumentos a funciones (la cantidad de sobrecargas necesarias crece fácilmente exponencialmente). It (io::stream) hace las siguientes restricciones:

Cada uno de estos miembros construye una instancia de corriente y la asocia con una instancia de la Device T construido a partir de las listas dadas de argumentos. Los constructores T involucrados deben tomar todos los argumentos por valor o referencia constante.

Bueno, pero el constructor dice tee_device

Construye una instancia de tee_device basado en el par de fregaderos dado. Cada parámetro de función es una referencia no constante si el argumento de plantilla correspondiente es una secuencia o tipo de memoria intermedia de secuencia, y una referencia constante de lo contrario.

Eso no funcionará, por supuesto. io::stream proporciona otro constructor que toma un T como primer argumento. Esto funciona aquí (.. Compila, al menos, la aserción falla, aunque no he trabajado con boost::iostreams así que no puedo ayudar con eso)

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

Editar: Después de llamar a flush() o streaming << std::flush, la afirmación pasa .

+0

Wow ... no vi eso en la documentación. Trabajo impresionante, muchas gracias! – rlbond

2

probablemente usted tiene que configurarlo de la siguiente manera:

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); 
Cuestiones relacionadas