如何在可变参数模板中声明"implicit conversion"?
How to declare an "implicit conversion" in a variadic template?
我的目标是将数据发送到几个流。这可以通过使用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_0boostiostreamsdetailforward.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 ...>>>
在模板内。
谢谢!
注。(这是我的第一个帖子)&&(我的母语不是英语)
您已经完成了所要求的转换,因为类类型已经隐式地转换为它们的公共基类型,但这并不是解决错误所需要的。
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...)) {}
但是这不起作用,因为根据文档,如果tee_device
构造函数的参数是流,那么它们必须绑定到对非const的引用,所以它们必须是左值。第一个参数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) {}
};
相关文章:
- .cpp和.h文件中的模板专用化声明
- 未在作用域中声明unordered_map
- C++避免重复声明的语法是什么
- 如何确保C++函数在定义之前声明(如override关键字)
- 错误:未在此范围内声明'reverse'
- 奇怪的(对我来说)返回声明 - 在谷歌上找不到任何关于它的信息
- 为什么在定义函数之前先声明它
- 如何声明特征矩阵,然后通过嵌套循环初始化它
- #ifdef和未声明的标识符
- 没有显式声明的int[]中的foreach
- 在基于范围的for循环中使用结构化绑定声明
- 在将变量声明为引用时,堆在释放后使用
- C++:无法访问声明的受保护成员
- 为什么我不能在一个类的不同行中声明和定义成员变量?
- 我不明白为什么我声明一个空的内部结构并将其传递给构造函数
- 使用cmake从源代码构建MySQL连接器/C++失败(与以前的声明冲突)
- 在函数内部的声明中初始化数组,并在外部使用它
- 在 c++ 中是否有通过声明"implicit"数组分配?
- 前向声明模板类时"Implicit instantiation of undefined template"
- 如何在可变参数模板中声明"implicit conversion"?