gpt4 book ai didi

c++ - 如何在 Boost Serialization 中创建用于序列化的接口(interface)?

转载 作者:太空狗 更新时间:2023-10-29 21:42:34 25 4
gpt4 key购买 nike

我是新手,想实现一个接口(interface)强制用户实现serialize方法。此方法是模板,我不能定义为虚拟。

我希望用户只需要实现这样的功能:

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;
};

但它强制用户实现这两个方法并不是我想要的。

有什么办法可以做我想做的事吗?

谢谢

最佳答案

没有内置方法,但您当然可以通过适当的权衡取舍抽象任何您想要的接口(interface)。

这是一个使用自定义 PolyArchive 的想象解决方案,它可以是对 polymorphic_oarchivepolymorphic_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);
}

关于c++ - 如何在 Boost Serialization 中创建用于序列化的接口(interface)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25889668/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com