如何声明“隐式转换”在可变模板中? [英] How to declare an "implicit conversion" in a variadic template?

查看:193
本文介绍了如何声明“隐式转换”在可变模板中?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的目的是将数据发送到几个流。可以通过使用boost :: tee。但我想用可变模板编写一个包装器来使用几个流。

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.

问题是,我需要从后代struct到ancestor结构的隐式转换。

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;
}

错误是

 ..\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>&)'|

预期输出为22333。 (我有22,但没有333,即它没有第二行的主要工作很好)

The expected output is "22333". (I have "22", but have no "333". I.e. it's work well without the second line of main)

换句话说, p>

In other words, I need conversion from

template<typename T1,typename T2,typename T3,typename ... Ts>

stream<tee_device<T1,pu<T2, T3, Ts ...>>>

谢谢!

p.s。 (这是我的第一篇文章)&& (我不是母语)

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.

base_type tu 的可变特化中的构造函数是错误的:

The arguments to the base_type constructor in the variadic specialization of tu are wrong:

pu(T1& t1, T2& t2, T3& t3, Ts&... ts) : base_type(t2, t3, ts...) {}

您可以改为尝试:

pu(T1& t1, T2& t2, T3& t3, Ts&... ts) : base_type(t1, pu<T2, T3, Ts...>(t2, t3, ts...)) {}

但这不会工作,因为根据文档,如果 tee_device 构造函数是流,那么它们必须绑定到非const的引用,因此它们必须是lvalue。第一个参数 t1 符合该标准,但第二个参数,临时 pu 不符合。

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 argument t1 meets that criterion, but the second argument, a temporary pu, does not.

以下解决方案使用多重继承来合成小值 pu

The following solution uses multiple inheritance to synthesize an lvalue pu:

template <typename T>
struct hold
{
    T held;
    template <typename... Ts> hold(Ts&&... vs) : held(std::forward<Ts>(vs)...) {}
};

template<typename...> 
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;
    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...> : private hold<pu<T2, T3, Ts...>>
                             , public stream<tee_device<T1, pu<T2, T3, Ts...>>> 
{
    typedef stream<tee_device<T1, pu<T2, T3, Ts...>>> base_type;
    pu(T1& t1, T2& t2, T3& t3, Ts&... ts) : hold<pu<T2, T3, Ts...>>(t2, t3, ts...)
                                          , base_type(t1, this->held) {}
};

这篇关于如何声明“隐式转换”在可变模板中?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆