How would you serialize/deserialize this class using boost::serialization?
#include <vector>
struct Foo {
struct Bar {
std::vector<int> * data; // Must point to Foo::data
Bar( std::vector<int> * d ) : data(d) { }
};
std::vector<int> data;
std::vector<Bar> elements;
Foo() {
// do very time consuming calculation to populate "data" and "elements"
}
};
The constructor in Foo must not be executed when the objected is loaded from the serialized data, but if the object is default constructed the constructor must be evaluated.
It is okay to add a default constructor to Bar, but after serialization the Foo::Bar::data must point to the Foo::data.
EDIT: Following is a non-working implementation of my attempt
This is my attempt based on the hints from @Matthieu. The problem is that when I deserialize Foo, I get no elements in Foo::data and Foo::elements.
struct Foo {
struct Bar {
std::vector<int> * data;
Bar( ) : data( 0 ) { }
Bar( std::vector<int> * d ) : data(d) { }
template<class Archive>
void serialize(Archive & ar, const unsigned int version) {
ar & data;
}
};
std::vector<int> data;
std::vector<Bar> elements;
Foo() {
std::cerr << "Running default constructor" << std::endl;
data.push_back(1);
data.push_back(2);
data.push_back(3);
data.push_back(4);
data.push_back(5);
elements.push_back( Bar( &data ) );
elements.push_back( Bar( &data ) );
elements.push_back( Bar( &data ) );
}
template<class Archive>
Foo( Archive & ar ) {
ar >> data; // is this corrent?
ar >> elements;
}
private:
BOOST_SERIALIZATION_SPLIT_MEMBER();
friend class boost::serialization::access;
template<class Archive>
void save(Archive & ar, const unsigned int version) const {
const std::vector<int> * data_ptr = &data;
// should data be seriliazed as pointer...
// it is used as a pointer in Bar
ar << data_ptr;
ar << elements;
}
};
int main(int argc, const char *argv[])
{
#if 0
// serialize
Foo foo;
boost::archive::text_oarchive oar(std::cout);
oar << foo;
#else
// deserialize
boost::archive::text_iarchive oar(std::cin);
Foo foo(oar);
#endif
std::cerr << foo.data.size() << std::endl;
std::cerr << foo.elements.size() << std::endl;
std::cerr << (&foo.data) << std::endl;
for( const auto& a : foo.data )
std::cerr << a << " ";
std::cerr << std::endl;
for( const auto& a : foo.elements)
std::cerr << a.data << " ";
std::cerr << std::endl;
return 0;
}
See Question&Answers more detail:os