c++ - 如何在可变参数模板中声明 "implicit conversion"?

标签 c++ variadic-templates derived-class variadic boost-iostreams

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

问题是我需要从后代结构到祖先结构的隐式转换。或者类似的东西。

#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”。也就是说,没有 main 的第二行它也能正常工作)

换句话说,我需要从

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

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

在模板中。

谢谢!

附注(这是我的第一篇文章)&&(我不是母语人士)

最佳答案

您已经有了您所要求的转换,因为类类型已经可以隐式转换为其公共(public)基类型,但这不是您解决错误所需要的。

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

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...)) {}

但这行不通,因为根据 documentation ,如果 tee_device 构造函数的参数是流,那么它们必须绑定(bind)到对非常量的引用,因此它们必须是左值。第一个参数 t1 符合该标准,但第二个参数,一个临时的 pu,不符合。

以下解决方案使用多重继承来合成一个左值 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) {}
};

关于c++ - 如何在可变参数模板中声明 "implicit conversion"?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30524816/

相关文章:

c++ - 在 CMake 中添加多个可执行文件

C++ 结构 "Incomplete type is not allowed"

c++ - 是否可以在 C++14 中创建具有可选模板参数的类型元组?

Java Class.newInstance 错误

c++ - 传递和转换方法指针

c++ - 数组还是 vector ?

c++ - 分配后如何用字符串填充字符?

c++ - 这是使用 sizeof...() 运算符的错误吗?

c++ - 在可变模板函数中为每个模板类型调用 void 函数?

c# - 如何从基类型中声明的方法返回派生类型