#c #serialization #boost #deserialization
#c #сериализация #повышение #Десериализация
Вопрос:
Я хотел бы использовать повышающую сериализацию для сериализации / десериализации данных в экземпляре класса. Идея заключается в том, что класс должен инкапсулировать данные, а также детали сериализации и десериализации. Это отлично работает для сериализации с использованием ar << this
, но сопоставимая десериализация с использованием ar >> this
выдает ошибку компиляции
error: cannot bind non-const lvalue reference of type ‘const q*amp;’ to an rvalue of type ‘const q*’
Ниже приведен полный рабочий код с закомментированной моей некомпилируемой restoreit
функцией. Это явно упрощение моего реального кода, но вопрос тот же. Как я могу инкапсулировать метод десериализации в свой класс?
#include <fstream>
#include <iostream>
#include <map>
#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/text_iarchive.hpp>
#include <boost/serialization/map.hpp>
class q
{
public:
q() : f_() { }
void setup() { f_.insert(std::make_pair(18,10)); }
int getcount() { return f_.size(); }
void storeit(const std::string amp;name)
{
std::ofstream ofs(name);
boost::archive::text_oarchive ar(ofs);
ar << this;
}
void restoreit(const std::string amp;name) const
{
std::ifstream ifs(name);
boost::archive::text_iarchive ia(ifs);
// The following line gives the error: cannot bind non-const lvalue reference of type ‘const q*amp;’ to an rvalue of type ‘const q*’
// ia >> this;
}
private:
std::map<int,int> f_;
friend class boost::serialization::access;
template<class Archive>
void serialize(Archive amp; ar, const unsigned int version)
{
ar amp; f_;
}
};
int main(void)
{
const std::string name = "/tmp/blah";
q foo;
foo.setup();
foo.storeit(name);
q foo2;
// I want to use foo2.restore(name) here
{
std::ifstream ifs(name);
boost::archive::text_iarchive ia(ifs);
ia >> foo2;
}
}
Комментарии:
1. отлично компилируется на последних версиях gcc и clang ( godbolt.org/z/ShyPlf ). Какую версию компилятора / настроек / boost вы используете?
2. Это с gcc 8.2.0 с повышением 1.65. Опубликованный код компилируется нормально, но, как говорится в комментарии внутри
restoreit()
функции, раскомментирование строки прерывает компиляцию.
Ответ №1:
Вам нужно удалить const из restoreit
определения. Во время восстановления f_
изменяется карта — вы можете сделать это только в неконстантной функции-члене.
void restoreit(const std::string amp;name)
{
std::ifstream ifs(name);
boost::archive::text_iarchive ia(ifs);
ia >> *this;
}