问题描述
我正在使用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的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!