我是新手,我想实现一个接口来强制用户实现序列化方法。此方法是模板,我不能定义为虚拟方法。
我希望用户只需要实现以下功能:
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;
};
但是它迫使用户实现这两种方法,这不是我想要的。
有什么办法可以做我想要的吗?
谢谢
没有内置的方法,但是您当然可以始终以适当的权衡取舍您想要的任何接口。
这是一个设想的解决方案,该解决方案使用自定义PolyArchive
,该自定义可以引用polymorphic_oarchive
或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童话般的尘土来实现一下实现:
void MyClass::serialize(PolyArchive ar, unsigned) {
boost::apply_visitor(make_visitor([=](auto& ar) {
ar & data_member;
}), ar);
}
精明的读者会发现用户仍然提供模板方法,但是将其隐藏在实际上PolyArchive
在编译时需要花费时间的虚拟方法中。
观看Live On Coliru上的打印:
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);
}
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句