升压类的序列化,在成员类型的变化 [英] Boost class serialization, change in member types

查看:100
本文介绍了升压类的序列化,在成员类型的变化的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

一个人如何手柄开关系列化成员的类型,而保持与previous存档的兼容性?例如。我想改变浮法/ INT 双/为size_t

How does one handle switching the type of serialized members while retaining compatability with previous archive? E.g. I want to change float/int to double/size_t.

我知道我可以递增版本号,但使code凌乱。是否有不同的方式来处理这个问题?如果它使不同,成员被序列直通 MAKE_NVP

I know I can increment version number but that makes code messy. Is there a different way to handle that? If it makes difference, the members are serialized thru MAKE_NVP.

推荐答案

您可以使用版本参数版本。文档给出了这样的例子:的http://www.boost.org/doc/libs/1_55_0/libs/serialization/doc/tutorial.html#versioning

You can use the version parameter to version. The documentation gives this example: http://www.boost.org/doc/libs/1_55_0/libs/serialization/doc/tutorial.html#versioning

请注意如何序列化过程中的版本是由 BOOST_CLASS_VERSION 宏指定。

Note how the version during serialization is specified by the BOOST_CLASS_VERSION macro.

下面是一个使用你的数据结构的以下版本概念证明:看到它的直播在Coliru

Here's a proof of concept using the following versions of your data struct: See it Live On Coliru

struct DataV0
{
    float f = 3.14;
    int   i = 42;

    template<class Archive>
    void serialize(Archive & ar, const unsigned int version)
    {
        if (0 != version) 
            throw std::runtime_error("Unsupported version");

        ar & f;
        ar & i;
    }
};

现在,在你的V1的序列化格式,你已经改变了类型,在你的问题:

Now, in your V1 serialization format, you have changed the types as in your question:

struct DataV1
{
    double d  = 3.14;
    size_t ul = 42;

    template<class Archive>
    void serialize(Archive & ar, const unsigned int version)
    {
        switch(version)
        {
            case 0:
                { 
                    DataV0 old;
                    ar & old.f;
                    ar & old.i;

                    d = old.f;
                    assert(old.i >= std::numeric_limits<size_t>::min());
                    assert(old.i <= std::numeric_limits<size_t>::max());
                    ul = static_cast<size_t>(old.i);
                }
                break;
            case 1:
                ar & d;
                ar & ul;
                break;
        }
    }
};

BOOST_CLASS_VERSION(DataV1, 1)

一个完整的测试程序:

template <typename Data>
std::string to_string(Data d)
{
    std::ostringstream oss;
    boost::archive::text_oarchive oa(oss);

    oa << d;

    return oss.str();
}

template <typename Data>
bool verify(std::string const& text)
{
    std::istringstream iss(text);
    boost::archive::text_iarchive ia(iss);

    Data d;
    ia >> d;

    return text == to_string(d);
}

int main()
{
    std::string v0text = to_string(DataV0());
    std::string v1text = to_string(DataV1());

    std::cout << v0text << '\n';
    std::cout << v1text << '\n';

    std::cout << "v0 as v0: " << std::boolalpha << verify<DataV0>(v0text) << "\n";
    std::cout << "v0 as v1: " << std::boolalpha << verify<DataV1>(v0text) << "\n";

    std::cout << "v1 as v1: " << std::boolalpha << verify<DataV1>(v1text) << "\n";
    try {
        std::cout << "v1 as v0: " << std::boolalpha << verify<DataV0>(v1text) << "\n";
    } catch (std::exception const& e)
    {
        std::cerr << "Threw the expected '" << e.what() << "'\n";
    }

}

打印:

22 serialization::archive 10 0 0 3.1400001 42
22 serialization::archive 10 0 1 3.1400000000000001 42
v0 as v0: true
v0 as v1: false
v1 as v1: true
v1 as v0: Threw the expected 'Unsupported version'

这篇关于升压类的序列化,在成员类型的变化的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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