如何在Boost序列化中创建序列化接口? [英] How to create a interface for serialization in Boost Serialization?

查看:108
本文介绍了如何在Boost序列化中创建序列化接口?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是新手,我想实现一个接口来强制用户实现序列化方法.此方法是模板,我无法定义为虚拟方法.

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_oarchivepolymorphic_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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆