c++ - Boost类序列化,成员类型的改变

标签 c++ serialization boost boost-serialization

如何处理切换序列化成员的类型,同时保持与以前存档的兼容性?例如。我想将 float/int 更改为 double/size_t

我知道我可以增加版本号,但这会使代码变得困惑。有不同的方法来处理吗?如果有所不同,成员将通过 MAKE_NVP 序列化。

最佳答案

您可以使用version 参数来进行版本控制。文档给出了这个例子:http://www.boost.org/doc/libs/1_55_0/libs/serialization/doc/tutorial.html#versioning

注意序列化期间的版本是如何由 BOOST_CLASS_VERSION 宏指定的。

这是使用以下数据结构版本的概念证明: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 序列化格式中,您已经更改了问题中的类型:

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'

关于c++ - Boost类序列化,成员类型的改变,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23230369/

相关文章:

c++ - 我可以在 C++ 中有一个 "type of types"吗?

c++ - 当 UBSAN (-fsanitize=undefined) 发现未定义行为时触发测试失败

c++ - 浮点类型的编译时操作

c++ - 在 read() 之前检查 boost::asio 缓冲区数据是否存在

python - 将 Boost Python 与 shared_ptr<const T> 一起使用

c++ - Visual Studio 2013 是否提供了对 c++11 的 high_performance_clock 的改进?

c++ - 在 C++11 之前使用 Iterator 与 [] 循环遍历 vector

c++ - 带有 boost 的 XML 序列化( '.serialize' 的左边必须有类/结构/union )

javascript - "Uncaught TypeError: Converting circular structure to JSON"-- JSON.stringify() 的替代品?

java - 对象输出和输入问题,仅打印输入的第一行