Повысить сериализацию - добавление в класс матриц броненосцев, имеющих пространства имен - PullRequest
0 голосов
/ 29 марта 2020

Я успешно сериализовал броненосец без матриц классов:

#include <iostream>
#include <fstream>
#include <boost/archive/binary_oarchive.hpp>
#include <boost/archive/binary_iarchive.hpp>
#include <armadillo>
#include <boost/serialization/split_member.hpp>

BOOST_SERIALIZATION_SPLIT_FREE(arma::mat)

namespace boost { 
namespace serialization {

template<class Archive>
void save(Archive & ar, const arma::mat &t, unsigned int version)
{
    ar & t.n_rows;
    ar & t.n_cols;
    const double *data = t.memptr();
    for(int K=0; K<t.n_elem; ++K)
        ar & data[K];
}

template<class Archive>
void load(Archive & ar, arma::mat &t, unsigned int version)
{
    int rows, cols;
    ar & rows;
    ar & cols;
    t.set_size(rows, cols);
    double *data = t.memptr();
    for(int K=0; K<t.n_elem; ++K)
        ar & data[K];
}
}}
int main() {

  arma::mat A = arma::randu<arma::mat>(4,5);

  std::ofstream outputStream;
  outputStream.open("bin.dat");
  std::ostringstream oss;
  boost::archive::binary_oarchive oa(outputStream);
  oa & A;
  outputStream.close();

  arma::mat B;
  std::ifstream inputStream;
  inputStream.open("bin.dat", std::ifstream::in);
  boost::archive::binary_iarchive ia(inputStream);
  ia & B;
  return 0;
}

Но моя конечная цель - иметь матрицы арма внутри класса, наряду с типичными типами данных (int, double, float и др. * 1017). *.) и сможет либо сериализовать все, либо указать c данные из класса. Я также заставил его работать, чтобы обычные типы данных могли быть сериализованы:

#include <iostream>
#include <fstream>
#include <boost/archive/binary_oarchive.hpp>
#include <boost/archive/binary_iarchive.hpp>
#include <sstream>
#include <boost/serialization/split_member.hpp>


class Gear {
  public:
    template<typename Archive>
    void serialize(Archive& ar, unsigned int version) { ar & v; }

    void setV (const double& _v) { v = _v; }
    double getV () { return v; }

    void status () { std::cout << "v = " << v << std::endl; }

  private:
    double v;
};

class Car {
  public:
    template<typename Archive>
    void serialize(Archive& ar, unsigned int version) {
      ar & hp;
      ar & x;
    }

    void setHP (const int& _hp) { hp = _hp; }
    void setGear (Gear* _Gear) { x = _Gear; }
    void status () { std::cout << "hp = " << hp << " Gear with v = " << x->getV() <<  std::endl; }

  private:
    int hp;
    Gear *x;
};

int main() {
  // Define new Gear:
  Gear* g = new Gear();
  g->setV(2.5);
  g->status();

  // Expectation is Car sets up the Gear.
  Car c;
  c.setHP(80);
  c.setGear(g);
  //c.status();




  std::ofstream outputStream;
  outputStream.open("bin.dat");
  std::ostringstream oss;
  boost::archive::binary_oarchive oa(outputStream);
  oa & c;
  outputStream.close();

  Car b;
  std::ifstream inputStream;
  inputStream.open("bin.dat", std::ifstream::in);
  boost::archive::binary_iarchive ia(inputStream);
  ia & b;
  b.status();
  return 0;


}

Так что это прекрасно работает, но я хочу включить код arma (по существу) в класс. Я попытался поместить код армы в класс следующим образом:

class Car {
  public:
    template<typename Archive>
    void serialize(Archive& ar, unsigned int version) {
      ar & hp;
      ar & x;
    }

  namespace boost { 
  namespace serialization {

  template<class Archive>
  void save(Archive & ar, const arma::mat &t, unsigned int version)
  {
    ar & t.n_rows;
    ar & t.n_cols;
    const double *data = t.memptr();
    for(int K=0; K<t.n_elem; ++K)
        ar & data[K];
  }

  template<class Archive>
  void load(Archive & ar, arma::mat &t, unsigned int version)
  {
    int rows, cols;
    ar & rows;
    ar & cols;
    t.set_size(rows, cols);
    double *data = t.memptr();
    for(int K=0; K<t.n_elem; ++K)
        ar & data[K];
  }
  } }  

    arma::mat A;// = arma::randu<arma::mat>(4,5);

    void setHP (const int& _hp) { hp = _hp; }
    void setGear (Gear* _Gear) { x = _Gear; }
    void status () { std::cout << "hp = " << hp << " Gear with v = " << x->getV() << A<< std::endl; }

  private:
    int hp;
    Gear *x;
};

А затем в int main ():

  Car c;
  c.setHP(80);
  c.setGear(g);
  c.A = arma::randu<arma::mat>(4,5);

После попытки скомпилировать попытку, я получаю ошибки:

g++ -std=c++11 arma_serial_binary_versuch.cpp -larmadillo -lboost_serialization
arma_serial_binary_versuch.cpp:52:3: error: expected unqualified-id before ‘namespace’                                                     
   namespace boost {                                                                                                                       
   ^                                                                                                                                       
arma_serial_binary_versuch.cpp:121:1: error: expected ‘}’ at end of input                                                                  
 }                                                                                                                                         
 ^                                                                                                                                         
arma_serial_binary_versuch.cpp: In member function ‘void Car::serialize(Archive&, unsigned int)’:                                          
arma_serial_binary_versuch.cpp:48:12: error: ‘hp’ was not declared in this scope                                                           
       ar & hp;
            ^
arma_serial_binary_versuch.cpp:49:12: error: ‘x’ was not declared in this scope
       ar & x;
            ^
arma_serial_binary_versuch.cpp: At global scope:
arma_serial_binary_versuch.cpp:50:5: error: expected unqualified-id at end of input
     }

Я читал, что невозможно работать с пространствами имен внутри класса, но я не уверен, что это можно обойти. У кого-нибудь есть идеи / рекомендации?

...