C++ boost::variant并获取要为msgpack编码的数据
我使用boost recursive variant来存储变量数据,我希望使用msgpack对变量数据进行编码,我需要获取原始数据以将其传递到encode()函数(见下文) 我在下面的encode()函数中尝试了三种不同的选项,但都不起作用。备选方案是什么C++ boost::variant并获取要为msgpack编码的数据,c++,encode,boost-variant,C++,Encode,Boost Variant,我使用boost recursive variant来存储变量数据,我希望使用msgpack对变量数据进行编码,我需要获取原始数据以将其传递到encode()函数(见下文) 我在下面的encode()函数中尝试了三种不同的选项,但都不起作用。备选方案是什么 typedef std::vector<boost::recursive_variant_> vector_rvariant_t; typedef std::map<std::string, boost::recursiv
typedef std::vector<boost::recursive_variant_> vector_rvariant_t;
typedef std::map<std::string, boost::recursive_variant_> map_rvariant_t;
typedef boost::make_recursive_variant <bool, boost::uint8_t, boost::uint32_t,
boost::int32_t, double, std::string, boost::uuids::uuid,
vector_rvariant_t, map_rvariant_t > ::type rvariant_type;
/**
Wrapper class for boost::make_recuverise_variant<>::type
*/
class rvariant {
public:
// encode the _data to msgpack buffer
//NEED HELP for this function.
void encode(msgpack::sbuf& sbuf) {
// msgpack::pack(sbuf, (*type_)data_);
// msgpack::pack(sbuf, boost::get<typeid(data_)>(data_));
// msgpack::pack(sbuf, boost::get<*type_>(data_));
}
// constructor
explicit template <typename T> rvariant(const T& data) {
data_ = data;
type_ = (std::type_info*)&typeid(data);
}
// operator=
template <typename T> rvariant& operator=(const T& data) {
data_ = data;
type_ = (std::type_info*)&typeid(data);
return *this;
}
// get the data
template<typename T> T get() {
return boost::get< T >(data_);
}
private:
rvariant_type data_;
std::type_info* type_;
};
typedef标准::向量变量;
typedef std::映射变量;
typedef boost::make_recursive_variant::type rvariant_type;
/**
boost::make\u recurverise\u variant::type的包装器类
*/
阶级变异{
公众:
//将_数据编码到msgpack缓冲区
//需要此功能的帮助。
无效编码(msgpack::sbuf和sbuf){
//msgpack::pack(sbuf,(*type_uu)数据);
//msgpack::pack(sbuf,boost::get(data_));
//msgpack::pack(sbuf,boost::get(data_));
}
//建造师
显式模板变量(常量和数据){
数据=数据;
类型(std::类型信息*)和类型ID(数据);
}
//运算符=
模板变量和运算符=(常量和数据){
数据=数据;
类型(std::类型信息*)和类型ID(数据);
归还*这个;
}
//获取数据
模板T get(){
返回boost::获取(数据);
}
私人:
变量类型数据;
标准::类型信息*类型信息;
};
我认为您使用的std::type\u info
方式与Boost::Variant不兼容
想法:
variant.which
模板
结构变量保存访问者:boost::static\u访问者{
变体保存访问者(存档和存档):m_ar(存档){}
模板
void运算符()(T常量和值)常量{
m_ar我认为您使用的std::type_info
方式与Boost::Variant不一样
想法:
使用与提供的代码类似的代码包装您的调用,以编码您自己的标记。通过使用访问者,您基本上将自己限制在Boost.Variant库的公共界面上。替代方法:使用Variant.which
不要试图利用boost::variant的内部标记和数据存储,因为它以后可能会更改。请记住,boost.variant可能会根据编译器功能和模板参数的属性以不同的方式分配其内部数据(例如,引用类型会被特殊处理)。相反,请分别对标记进行编码(如步骤1所示),然后分别对(键入的)数据进行编码
我希望这会有所帮助。我想简短的版本是这样的:你的方法虽然比我描述的更直接,但很难正确,因为你依赖于变体的内部
编辑:我查看了Boost.Serialization源代码。它可能会有帮助:
编辑:为了说明(并使答案更加完整),下面是Boost.Serialization中的访问者的样子(请参见上面的链接):
模板
结构变量保存访问者:boost::static\u访问者{
变体保存访问者(存档和存档):m_ar(存档){}
模板
void运算符()(T常量和值)常量{
m_ar@phooji:Thx.当我尝试静态访问时,我会看到下面的错误/home/rjoshi/trunk/vendor/opensource/boost/v1.45.0/include/boost/variant/variant.hpp:832:error:return语句和一个值,在返回'void'的函数中,你建议如何使用variant.哪个?@rjoshi:de>operator()
重载应该具有返回类型SOMETYPE
。对于中的,请仔细查看serialization/variant.hpp(上面的链接)中的代码。@phooji:所以基本上我需要编写静态的\u visitor和重载函数()对于每种可能的转换类型。递归向量和递归映射如何定义为typedef std::vector vector\u rvariant\u t;typedef std::map map\u rvariant\u t;@rjoshi:正确。对于任意大的类型,这取决于msgpack的工作方式(我不熟悉它)。如果它需要预先知道大小,那么您可以编写一个单独的访问者来计算大小(递归地,通过保持运行总数)。如果不需要显式记录大小,则只需在数据流中使用一个“分隔符”来帮助您以后重新构建它。从概念上讲,这与JSON等数据格式类似。@phooji:msgpack不需要大小,可以处理所有基元类型和STL容器,包括list和map。问题是我懒于编写e访问所有数据类型和可能的转换,因此请考虑是否有直接类型转换变体数据的方法。但看起来没有替代方法。我将增加您的答案,并等待其他人是否提供我正在寻找的内容。如果没有,则会接受您的答案:).Thx。@phooji:Thx。当我尝试静态访问时,我会得到下面的eerror/home/rjoshi/trunk/vendor/opensource/boost/v1.45.0/include/boost/variant/variant.hpp:832:错误:return-s
template<class Archive>
struct variant_save_visitor : boost::static_visitor<> {
variant_save_visitor(Archive& ar) : m_ar(ar) {}
template<class T>
void operator()(T const & value) const {
m_ar << BOOST_SERIALIZATION_NVP(value);
}
private:
Archive & m_ar;
};