How do you serialize a derived member class (cereal)

225 Views Asked by At

currently I'm trying to serialize a derived class but when I try to serialize it, only the base serialize is called rather than the derived serialization, so when I try to call load the file, the derived member returns a corrupted number. Is there anyway I can get around to doing this ?

what I'm trying to do is something similar to this

class BASE
{
public:
   BASE() {};
   int base_mem{};
   template <class T>
   void serialize(T& t)
   {
      t(base_mem);
   }
}

class DERIVED : public BASE
{
public:
   DERIVED() {};
   int der_mem{};
   template<class T>
   void serialize(T& t)
   {
      t(cereal::base_class<BASE>(this), der_mem);
   }
}


void main()
{
   std::shared_ptr<BASE>dr = std::make_shared<DERIVED>();
   std::ofstream ofs("Output.out", std::ios::binary);
   cereal::BinaryOutputArchive out(ofs);
   out(dr);
}

1

There are 1 best solutions below

0
G4lActus On

I just came across your answer, here is my take on it. If you use plain C++ just remove the Rcpp lines and replace the stream insertion with std::cout.

// [[Rcpp::depends(Rcereal)]]
#include <fstream>
#include <memory>
#include <cereal/archives/binary.hpp>
#include <cereal/types/base_class.hpp>
#include <cereal/types/memory.hpp>
#include <Rcpp.h>

class Base
{
public:
  Base(){};
  
  int base_mem{};
  template <class Archive>
  void serialize(Archive& archive)
  {
    archive(base_mem);
  }
};


class Derived: public Base
{
public:
  Derived(){};
  int der_mem{};
  template<class Archive>
  void serialize(Archive& archive)
  {
    archive(cereal::base_class<Base>(this), der_mem);
  }
};


// [[Rcpp::export]]
int main() 
{
  {
    Base bs{};
    bs.base_mem = 42;
    std::shared_ptr<Derived> shr_ptr_dr = std::make_shared<Derived>();
    shr_ptr_dr.get()->der_mem = 43;
    shr_ptr_dr.get()->base_mem = 45;
    
    std::ofstream os("Backend/Output.bin", std::ios::binary);
    cereal::BinaryOutputArchive oarchive(os);
    oarchive(bs, shr_ptr_dr);
  }
  
  {
    std::ifstream is("Backend/Output.bin", std::ios::binary);
    cereal::BinaryInputArchive iarchive(is);
    Base bs{};
    std::shared_ptr<Derived> shr_ptr_dr;
    iarchive(bs, shr_ptr_dr);
    
    Rcpp::Rcout << bs.base_mem << std::endl;
    Rcpp::Rcout << shr_ptr_dr.get()->der_mem << std::endl;
    Rcpp::Rcout << shr_ptr_dr.get()->base_mem << std::endl;
    
    
  }
}