簡體   English   中英

如何在Boost Serialization中創建序列化接口?

[英]How to create a interface for serialization in Boost Serialization?

我是新手,我想實現一個界面來強制用戶實現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;
  };

但它迫使用戶實現這兩種方法並不是我想要的。

有什么辦法可以做我想要的嗎?

謝謝

當然,沒有內置的方法,你可以通過正確的權衡取舍來抽象出你想要的任何界面。

這是一個使用自定義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);
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM