Использование загрузочной сериализации для десериализации из функции-члена

#c #serialization #boost #deserialization

#c #сериализация #повышение #Десериализация

Вопрос:

Я хотел бы использовать повышающую сериализацию для сериализации / десериализации данных в экземпляре класса. Идея заключается в том, что класс должен инкапсулировать данные, а также детали сериализации и десериализации. Это отлично работает для сериализации с использованием ar << this , но сопоставимая десериализация с использованием ar >> this выдает ошибку компиляции

 error: cannot bind non-const lvalue reference of typeconst q*amp;’ to an rvalue of typeconst 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;
 }