Boost序列化:读取各种类型的数据 [英] Boost serialization : read varying type of data

查看:359
本文介绍了Boost序列化:读取各种类型的数据的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个C ++/CLI项目,该项目使用boost序列化来序列化三个不同的类.我想知道是否有可能解析boost序列化归档文件的第一行,以便知道在该归档文件中序列化了哪个类,然后创建一个适当类的对象并将该归档文件反序列化为该对象.该行将包含一个ID(可能是枚举类的int或值),以标识要序列化的类.

I have a C++ / CLI project that uses boost serialization to serialize three different classes. I would like to know if it is possible to parse the first line of the boost serialization archive in order to know what class was serialized in this archive, and then create an object of the appropriate class and deserialize the archive into the object. That line would contain an ID (maybe a int or value of an enum class) to identify which class was serialized.

推荐答案

文件格式已经由您选择的归档"实施方式处理.

The file format is already handled by your choice of Archive implementation.

实际上是boost::archive::text_oarchiveboost::archive::binary_oarchiveboost::archive::xml_oarchive.

只要您的存档类型本身没有变化,您就可以非常轻松地使用Boost Variant来区分您的有效负载.换句话说,让序列化框架为您完成工作,而不是围绕它进行录音":

As long as your archive type itself doesn't vary, you can very easily use a Boost Variant to distinguish your payloads. In other words, make the serialization framework do the work for you, instead of "duct taping" around it:

这是一个演示,可以在没有外部实际知道有效负载的情况下,对3个不同的(复合)有效负载和往返进行序列化:

Here's a demo that serializes 3 different (compound) payloads and roundtrips just fine without external knowledge of the payload actually there:

在Coliru上直播

#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/text_iarchive.hpp>

#include <boost/serialization/variant.hpp>
#include <boost/serialization/vector.hpp>
#include <boost/serialization/string.hpp>

#include <boost/serialization/access.hpp>

struct A {
    int simple;

  private:
    friend class boost::serialization::access;
    template <typename Ar> void serialize(Ar& ar, unsigned) {
        ar & simple;
    }
};

struct B {
    std::string text;

  private:
    friend class boost::serialization::access;
    template <typename Ar> void serialize(Ar& ar, unsigned) {
        ar & text;
    }
};

struct C {
    A composed_a;
    B composed_b;

  private:
    friend class boost::serialization::access;
    template <typename Ar> void serialize(Ar& ar, unsigned) {
        ar & composed_a & composed_b;
    }
};

struct FileContents { // conventions...
    boost::variant<A, B, C> payload;

  private:
    friend class boost::serialization::access;
    template <typename Ar> void serialize(Ar& ar, unsigned) {
        ar & payload;
    }
};


#include <sstream>
#include <boost/lexical_cast.hpp>

//////////////////////////////////////////////////////////////////////////////////////////////////////////////
// For our roundtrip test, implement streaming as well so we can independently check equivalence
inline static std::ostream& operator<<(std::ostream& os, A const& v) {
    return os << "A{" << v.simple << "}";
}
inline static std::ostream& operator<<(std::ostream& os, B const& v) {
    return os << "B{" << v.text << "}";
}
inline static std::ostream& operator<<(std::ostream& os, C const& v) {
    return os << "C{" << v.composed_a << ", " << v.composed_b << "}";
}

void roundtrip_test(FileContents const& original) {
    std::stringstream ss;
    {
        boost::archive::text_oarchive oa(ss);
        oa << original;
    }

    {
        boost::archive::text_iarchive ia(ss);

        FileContents clone;
        ia >> clone;

        std::string const before = boost::lexical_cast<std::string>(original.payload);
        std::string const after  = boost::lexical_cast<std::string>(clone.payload);

        std::cout << "Roundtrip '" << before << "': " << std::boolalpha << (before == after) << "\n";
    }
}

int main() {
    roundtrip_test({ A { 42 } });
    roundtrip_test({ B { "Life The Universe And Everything" } });
    roundtrip_test({ C { {42}, { "Life The Universe And Everything" } } });
}

输出为:

Roundtrip 'A{42}': true
Roundtrip 'B{Life The Universe And Everything}': true
Roundtrip 'C{A{42}, B{Life The Universe And Everything}}': true

这篇关于Boost序列化:读取各种类型的数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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