boost::variant 并获取数据以对 msgpack 进行编码
我正在使用 boost 递归变体来存储我想要使用 msgpack 进行编码的变体数据,我需要将原始数据传递到encode() 函数中(见下文)。
我在下面的encode()函数中尝试了三个不同的选项,但不起作用。替代方案是什么?
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_;
};
I am using boost recursive variant to store the variant data which I want to encode using msgpack for which I need to get the raw data to pass into encode() function (see below).
I tried three different options in encode() function below but doesn't work. What are the alternates?
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_;
};
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我认为您使用
std::type_info
的方式不适用于 Boost::Variant。想法:
使用类似于提供的代码此处 包装您的调用以对您自己的标签进行编码。通过使用访问者,您实际上会将自己限制在 Boost.Variant 库的公共接口上。替代方案:使用
variant.which
不要尝试利用 boost::variant 的内部标记和数据存储,因为它稍后可能会发生变化。请记住,Boost.Variant 可能会根据编译器功能和模板参数的属性(例如,引用类型被特殊处理)来不同地分配其内部数据。相反,单独编码标记(如步骤一),然后单独编码(类型化)数据。
我希望这有帮助。我想简短的版本是这样的:您的方法虽然比我所描述的更直接,但更难正确,因为您依赖于 Variant 的内部结构。
编辑:我查看了 Boost.Serialization 源代码。它可能会有所帮助: http://svn.boost.org/ svn/boost/trunk/boost/serialization/variant.hpp
编辑: 为了说明(并使答案更加独立),以下是 Boost.Serialization 中的访问者的外观像(见上面的链接):
I don't think you're using
std::type_info
in a way that works with Boost::Variant.Idea:
Use the code similar to that provided here to wrap your calls to encode your own tag. By using a visitor, you'll essentially restrict yourself to the public interface of the Boost.Variant library. Alternative: use
variant.which
Don't try to piggy back off of boost::variant's internal tagging and data storage, since it might change later. Keep in mind that Boost.Variant may allocate its internal data differently based on compiler features and based the properties of the template parameters (e.g. reference types are treated specially). Instead, encode the tag separately (as in step one) and then encode the (typed) data separately.
I hope that helps. I guess the short version is this: your approach, while more direct than what I've described, is harder to get right because you're relying on the internals of Variant.
Edit: I had a look at the Boost.Serialization source. It might help: http://svn.boost.org/svn/boost/trunk/boost/serialization/variant.hpp
Edit: To illustrate (and to make the answer more self-contained), here is what the visitor in Boost.Serialization looks like (see link above):