My aim is to send a data to several streams. It is possible by using boost::tee. But I want to write a wrapper with variadic template for using several streams.
The problem is that I need an implicit convertation from descendant struct to ancestor struct. Or something like that.
#include <boost/iostreams/tee.hpp>
#include <boost/iostreams/stream.hpp>
#include <fstream>
#include <iostream>
using namespace std;
namespace bio = boost::iostreams;
using bio::tee_device;
using bio::stream;
template<typename ... Ts>
struct pu;
template<typename T1,typename T2>
struct pu<T1,T2>:public stream<tee_device<T1,T2>>
{
typedef stream<tee_device<T1,T2>> base_type;
operator base_type() { return static_cast<base_type&>(*this); }
base_type& base = static_cast<base_type&>(*this);
pu(T1& t1, T2& t2): base_type(tee_device<T1,T2>(t1,t2)) {}
};
template<typename T1,typename T2,typename T3,typename ... Ts>
struct pu<T1,T2,T3,Ts...> : public stream<tee_device<T1,pu<T2, T3, Ts ...>>>
{
typedef stream<tee_device<T1,pu<T2, T3, Ts ...>>> base_type;
operator base_type() { return static_cast<base_type&>(*this); }
pu(T1& t1, T2& t2, T3& t3, Ts& ... ts) : base_type(t2,t3,ts...){}
};
int main()
{
pu<ostream,ostream> hT(cout,cout); hT<<"2";
pu<ostream,ostream,ostream> hR(cout,cout,cout); hR<<"3";
return 0;
}
The error is
..\boost_1_56_0\boost\iostreams\detail\forward.hpp|73|error: no matching function for call to
'boost::iostreams::tee_device<std::basic_ostream<char>, pu<std::basic_ostream<char, std::char_traits<char> >, std::basic_ostream<char, std::char_traits<char> > > >::tee_device(std::basic_ostream<char>&, const std::basic_ostream<char>&)'|
The expected output is "22333". (I have "22", but have no "333". I.e. it's work well without the second line of main)
In other words, I need conversion from
template<typename T1,typename T2,typename T3,typename ... Ts>
to
stream<tee_device<T1,pu<T2, T3, Ts ...>>>
inside the template.
Thanks!
p.s. (it's my first post) && (i'm not native speaker)
You already have the conversion that you ask for, because class types are already implicitly convertible to their public base types, but that is not what you need to solve the error.
The arguments to the
base_type
constructor in the variadic specialization oftu
are wrong:You could try this instead:
But that won't work because, according to the documentation, if the arguments to the
tee_device
constructor are streams then they must bind to references to non-const, so they must be lvalues. The first argumentt1
meets that criterion, but the second argument, a temporarypu
, does not.The following solution uses multiple inheritance to synthesize an lvalue
pu
: