Использование boost :: iostreams :: tee_device? - PullRequest
7 голосов
/ 22 марта 2009

Может кто-нибудь мне помочь?

Я пытаюсь сделать что-то вроде следующего:

#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

Кто-нибудь заставил это работать? Я знаю, что могу сделать свой собственный класс, но хочу знать, что я делаю неправильно.

Спасибо

Ответы [ 2 ]

10 голосов
/ 22 марта 2009

Вы используете версию перенаправления конструктора из io::stream, которая сама создает поток tee и передает все аргументы этому. C ++ 03 имеет только ограниченные возможности, когда дело доходит до пересылки аргументов в функции (количество перегрузок должно легко расти в геометрической прогрессии). Он (io::stream) имеет следующие ограничения:

Каждый из этих членов создает экземпляр потока и связывает его с экземпляром Устройства T, созданным из заданных списков аргументов. Конструкторы T должны принимать все аргументы по значению или константной ссылке.

Хорошо, но конструктор tee_device говорит

Создает экземпляр tee_device на основе заданной пары раковин. Каждый параметр функции является неконстантной ссылкой, если соответствующий аргумент шаблона является потоком или типом буфера потока, и константной ссылкой в ​​противном случае.

Это не сработает, конечно. 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 утверждение проходит.

2 голосов
/ 22 марта 2009

Возможно, вам нужно настроить его следующим образом:

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