本文介绍了加速序列化:未调用save_construct_data的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm using boost to serialize object without a default constructor, however I get a weird issue : save_construct_data is not being called !

以下是一个重现此问题的示例程序:

Bellow a sample program that reproduce this problem:

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;   
}

Test.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

and finally 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)

but it is only printing serialize Test ... (save_construct_data is not called)

我想念什么吗?

感谢您的帮助.

推荐答案

假设似乎是您正在构建walid::Test<T>.

The assumption appears to be that you are constructing walid::Test<T>.

但是,如果仔细观察,您会发现实际上并没有构造任何东西.

However, if you look closely, you will realize that you don't actually construct anything.

根据设计,Boost序列化(反)序列化(插入)左值.反序列化期间唯一需要构造的地方是序列化动态分配的对象时.

By design Boost Serialization (de)serializes (into) lvalues. The only place where construction is required during de-serialization is when serializing dynamically allocated objects.

您可以通过将实例的存储更改为例如来说服自己shared_ptr:

You can convince yourself by changing the storage of the instance to e.g. shared_ptr:

#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 ...

这篇关于加速序列化:未调用save_construct_data的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

11-01 16:51