如何在Boost序列化中创建序列化接口? [英] How to create a interface for serialization in Boost Serialization?
问题描述
我是新手,我想实现一个接口来强制用户实现序列化方法.此方法是模板,我无法定义为虚拟方法.
I am newbie and I want to implement an interface to force users to implement the serialize method. This method is template and I can not define as virtual.
我希望用户只需实现如下功能:
I would like the user only has to implement a function like this:
template<class Archive>
void serialize(Archive & ar, const unsigned int version)
{
...
};
我尝试创建此界面:
class interface_serializing
{
public:
virtual ~interface_serializing(void)
{ }
friend class boost::serialization::access;
virtual void serialize(boost::archive::polymorphic_iarchive & ar,
const unsigned int version) = 0;
virtual void serialize(boost::archive::polymorphic_oarchive & ar,
const unsigned int version) = 0;
};
但是它迫使用户实现这两种方法,这不是我想要的.
But it forces the user to implement these two methods and is not what I want.
有什么办法可以做我想做的事吗?
Is there any way to do what I want?
谢谢
推荐答案
虽然没有内置方法,但是您当然可以通过适当的权衡取舍抽象出您想要的任何接口.
There's no builtin way, but you can, of course, always abstract any interface you wish, with the right set of trade-offs.
这是一个想象中的解决方案,它使用自定义的PolyArchive
,该自定义PolyArchive
可能是对polymorphic_oarchive
或polymorphic_iarchive
的引用:
Here's one imagined solution that uses a custom PolyArchive
that could be a reference to either the polymorphic_oarchive
or polymorphic_iarchive
:
#include <boost/serialization/serialization.hpp>
#include <boost/archive/polymorphic_oarchive.hpp>
#include <boost/archive/polymorphic_iarchive.hpp>
#include <boost/archive/polymorphic_text_oarchive.hpp>
#include <boost/archive/polymorphic_text_iarchive.hpp>
#include <boost/variant.hpp>
#include <sstream>
using PolyArchive = boost::variant<
boost::archive::polymorphic_oarchive&,
boost::archive::polymorphic_iarchive&
>;
struct /*abstract*/ ISerializable {
virtual void serialize(PolyArchive, unsigned) = 0;
};
struct MyClass : ISerializable {
std::string data_member = "Morgana"; // something to serialize
// the one method we need to implement
virtual void serialize(PolyArchive ar, unsigned) override;
};
现在,让我们用一点C ++ 14妖精的尘土来实现一下实现:
Now, let's do the implementation a bit with a bit of C++14 fairy-dust:
void MyClass::serialize(PolyArchive ar, unsigned) {
boost::apply_visitor(make_visitor([=](auto& ar) {
ar & data_member;
}), ar);
}
精明的读者会发现用户仍然提供模板方法,但是将其隐藏在实际上 在编译时需要PolyArchive
的虚拟方法中.
The astute reader will spot that the user still supplies the template method, but hides it inside a virtual method that actually takes a PolyArchive
at compile time.
查看 在Coliru上直播 ,打印:
See it Live On Coliru, printing:
Serialized: 22 serialization::archive 11 0 0 7 Morgana
Roundtripped: 22 serialization::archive 11 0 0 7 Morgana
代码:
#include <boost/serialization/serialization.hpp>
#include <boost/archive/polymorphic_oarchive.hpp>
#include <boost/archive/polymorphic_iarchive.hpp>
#include <boost/archive/polymorphic_text_oarchive.hpp>
#include <boost/archive/polymorphic_text_iarchive.hpp>
#include <boost/variant.hpp>
#include <sstream>
using PolyArchive = boost::variant<
boost::archive::polymorphic_oarchive&,
boost::archive::polymorphic_iarchive&
>;
struct /*abstract*/ ISerializable {
virtual void serialize(PolyArchive, unsigned) = 0;
};
struct MyClass : ISerializable {
std::string data_member = "Morgana"; // something to serialize
// the one method we need to implement
virtual void serialize(PolyArchive ar, unsigned) override;
};
int main()
{
std::stringstream ss;
{
// serialize:
boost::archive::polymorphic_text_oarchive output(ss);
MyClass object;
output << object;
}
// Debug dump;
std::cout << "Serialized: " << ss.str();
{
// read back:
boost::archive::polymorphic_text_iarchive input(ss);
MyClass cloned;
input >> cloned;
std::cout << "Roundtripped: ";
boost::archive::polymorphic_text_oarchive pta(std::cout);
pta << cloned;
}
}
////////////////////////////////
// implementation:
namespace /*detail*/ {
template <typename F> struct wrap_visitor : boost::static_visitor<> {
wrap_visitor(F const& f) : f_(f) { }
wrap_visitor(F&& f) : f_(std::move(f)) { }
template<typename... T> void operator()(T&&... t) const {
f_(std::forward<T>(t)...);
}
private:
F f_;
};
template <typename F>
wrap_visitor<F> make_visitor(F&& f) {
return std::forward<F>(f);
}
}
void MyClass::serialize(PolyArchive ar, unsigned) {
boost::apply_visitor(make_visitor([=](auto& ar) {
ar & data_member;
}), ar);
}
这篇关于如何在Boost序列化中创建序列化接口?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!