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
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} ) ;
}
}
}
this code is supposed to print :
serialize Test ...
call save_construct_data Test ...
but it is only printing serialize Test ...
(save_construct_data is not called)
Am I missing something ?
Thanks for your help.
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.
By design Boost Serialization (de)serializes (into) lvalues. The only place where construction is required during de-serialization is when serializing dynamically allocated objects.
You can convince yourself by changing the storage of the instance to e.g.
shared_ptr
:Live On Coliru
Prints