【问题标题】:boost serialization: save_construct_data not called增强序列化:未调用 save_construct_data
【发布时间】:2015-07-06 21:53:04
【问题描述】:

我正在使用 boost 来序列化没有默认构造函数的对象,但是我遇到了一个奇怪的问题:save_construct_data 没有被调用!

下面是重现此问题的示例程序:

main.cpp

#include <vector>
#include <iostream>
#include "Test.h"

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

int main()
{
    using T = float;
    walid::Test<T> instance ( 2, {2.3f, -0.5f} ) ;

    std::ofstream ofs ( "data" );
    boost::archive::text_oarchive oa ( ofs );    
    oa << instance;   
}

测试.h

#ifndef __Test_HEADER__
#define __Test_HEADER__

#include <list>
#include <vector>
#include <iostream>
#include <initializer_list>

namespace walid
{ 
    template<typename T>
    class Test
    {
      public:
        std::vector<T> elements;
    int in_dim ;

    Test(int input_dim, std::initializer_list<T> elem)
    {
      in_dim = input_dim;
      elements = std::vector<T>(elem);
    }
    void start(){};
    void stop(){};
    };
}

#include "Test_serialization.inl"

#endif

最后是 Test_serialization.inl

namespace boost {
namespace serialization {

    template<class Archive, class T>
    inline void serialize(Archive & ar, walid::Test<T>& t, const unsigned int version)
    {
      std::cout<<"serialize Test ..."<<std::endl;
    }

    template<class Archive, class T>
    inline void save_construct_data ( Archive & ar, const walid::Test<T>* t, const unsigned int version )
    {
        std::cout<<"call save_construct_data Test ..."<<std::endl;

    }

    template<class Archive, class T>
    inline void load_construct_data ( Archive & ar, walid::Test<T>* t, const unsigned int version )
    {
        std::cout<<"call load_construct_data Test ..."<<std::endl;
        ::new ( t ) walid::Test<T> ( 2, {2.3f, -0.5f} ) ;
    }
}
}

这段代码应该打印出来:

serialize Test ... 
call save_construct_data Test ...

但它只打印serialize Test ...(不调用save_construct_data)

我错过了什么吗?

感谢您的帮助。

【问题讨论】:

    标签: c++ boost boost-serialization


    【解决方案1】:

    假设您正在构建walid::Test&lt;T&gt;

    但是,如果你仔细观察,你会发现你实际上并没有构建任何东西。

    根据设计,Boost 序列化(反)序列化(成)左值。反序列化过程中唯一需要构造的地方是序列化动态分配的对象时。

    您可以通过将实例的存储更改为例如shared_ptr:

    Live On Coliru

    #include <fstream>
    #include <boost/archive/text_oarchive.hpp>
    #include <boost/archive/text_iarchive.hpp>
    #include <boost/serialization/shared_ptr.hpp>
    #include <boost/serialization/serialization.hpp>
    
    #include <boost/shared_ptr.hpp>
    
    int main()
    {
        using T = float;
        using Test = walid::Test<T>;
    
        {
            boost::shared_ptr<Test> shared_instance(new Test(2, {2.3f, -0.5f}));
    
            std::ofstream ofs("data");
            boost::archive::text_oarchive oa(ofs);
            oa << shared_instance;
        }
    
        {
            boost::shared_ptr<Test> deserialized;
    
            std::ifstream ifs("data");
            boost::archive::text_iarchive ia(ifs);
            ia >> deserialized;
        }
    }
    

    打印

    call save_construct_data Test ...
    serialize Test ...
    call load_construct_data Test ...
    serialize Test ...
    

    【讨论】:

    • 感谢您的帮助,它可以工作,但是在尝试反序列化 boost::shared_ptr new_instance; 时会崩溃; std::ifstream ifs ( "数据" ); boost::archive::text_iarchive ia ( ifs ); ia >> new_instance;
    • @boussaffa 这对我来说不会失败:Live On Coliru。也许您正在做其他不同的事情(例如,您是否忘记在反序列化之前刷新/关闭数据 + oa?)。
    猜你喜欢
    • 1970-01-01
    • 2012-03-31
    • 2013-11-26
    • 2021-02-06
    • 2023-03-22
    • 1970-01-01
    • 1970-01-01
    • 2014-05-30
    • 2017-03-10
    相关资源
    最近更新 更多