I'm trying to use the boost serialization library to serialize a class. The serializing works just fine but when I try to read the contents that were wrote to a file a get an "input error" exception.
I read the Documentation of the boost serialization library and came up with the (1) to understand how to serialize and deserialize a class with non-default constructors. I was trying to keep as close to the example from the documentation as I could.
I tried removing ar & name from the serialize method (which the documentation example did) in the Book class which also resulted in an input stream error.
When debugging I recognized that the exception gets thrown in the load _access class in the load_primitive` function.
Source Code (1)
#include <fstream>
#include <filesystem>
#include <boost/serialization/access.hpp>
#include <boost/serialization/string.hpp>
#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/text_iarchive.hpp>
class Book
{
private:
std::string name;
friend class boost::serialization::access;
template<class Archive>
void serialize(Archive& ar, const unsigned int file_version)
{
ar & name;
}
public:
Book(std::string name): name(name) {}
};
namespace boost {
namespace serialization {
template<class Archive>
inline void save_construct_data(Archive& ar, Book* book, const unsigned int file_version)
{
ar << book->name;
}
template<class Archive>
inline void load_construct_data(Archive& ar, Book* book, const unsigned int file_version)
{
std::string name;
ar >> name;
::new(book)Book(name);
}
}
}
int main()
{
Book book("Harry Potter");
std::ofstream ofs("Book.txt");
boost::archive::text_oarchive oa(ofs);
oa << &book;
ofs.close();
Book* read;
std::ifstream ifs("Book.txt", std::ios::binary);
boost::archive::text_iarchive ia(ifs);
ia >> read;
ifs.close();
}
I am getting the following error
terminate called after throwing an instance of 'boost::archive::archive_exception'
what(): input stream error
Thanks in advance for any awnser. Felix
save_construct_data()andload_construct_data()should work together, but in your codesave_construct_data()is never called. This happens because it has incorrect signature:Book*should beconst Book*.You then get a stream error because serialization and deserialization are inconsistent with each other – serialization writes
Book::nameonce, inserialize(), but deserialization tries to read it twice, inload_construct_data()and inserialize().Complete working example (
main()is unchanged, except removingstd::ios::binary):I declared
save_construct_data()as afriendinside the class to simplify code. For some reason, if it is defined inboost::serializationnamespace, you need to add afrienddeclaration for that function in addition to befriendingboost::serialization::access. This is not mentioned in the documentation, but code doesn't compile without thatfrienddeclaration.