有没有办法使用boost序列化序列化迭代器?

时间:2018-02-22 15:53:17

标签: c++ boost-serialization

在我的项目中,我有一个包含和std :: list的类,在另一个类中,我维护一个指向该列表中间位置的迭代器。

我可以成功序列化列表,但迭代器成员变量导致问题。这是一个重现的程序:

#include <boost/serialization/list.hpp>
#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/text_iarchive.hpp>
#include <iostream>
#include <fstream>

class A
{
public:
  A(){}
  A(const std::list<int> & _i) : i(_i) {}
  virtual ~A(){}

  std::list<int> i;

  void display() {
    std::cout << "i:";
    for (const int j : i)
      std::cout << " " << j;
    std::cout << std::endl;
  }

private:
  friend class boost::serialization::access;
  //friend std::ostream & operator<<(std::ostream &os, const A &a);
  template<class Archive>
  void serialize(Archive &ar, const unsigned int version)
  {
    ar & i;
  }
};

class Stepper
{
public:
  Stepper() {}
  Stepper(const A& a)
    : p(a.i.size()>0 ? a.i.begin() : a.i.end()) {}

  std::list<int>::const_iterator p;

  void display() {
    std::cout << "p: " << *p << std::endl;
  }

  void step() { p++; }

private:
  friend class boost::serialization::access;
  //friend std::ostream & operator<<(std::ostream &os, const A &a);
  template<class Archive>
  void serialize(Archive &ar, const unsigned int version)
  {
    ar & p;
  }
};

int main()
{
  {
    A a({5,6,7});
    Stepper sa(a);
    a.display();
    sa.display();
    sa.step();
    sa.display();

    std::ofstream ofs( "a.txt" );
    boost::archive::text_oarchive ar(ofs);
    ar & a;
    ar & sa;
  }

  A b;
  Stepper sb;
  {
    std::ifstream ifs( "a.txt" );
    boost::archive::text_iarchive ar(ifs);
    ar & b;
    ar & sb;
  }

  b.display();
  sb.display();

  return 0;
}

在这个程序中,A类可以没有问题地序列化。 (删除ar&sa东西..)但不幸的是,当尝试序列化包含迭代器的类(上面的确切代码)时,我得到以下编译错误:

[..snip..]

testser.cpp:72:10:   required from here /usr/include/boost/serialization/access.hpp:116:11:
error: ‘struct std::_List_const_iterator<int>’ has no member named ‘serialize’
         t.serialize(ar, file_version);
         ~~^~~~~~~~~


[..snip..]

testser.cpp:81:10:   required from here /usr/include/boost/serialization/access.hpp:116:11:
error: ‘struct std::_List_const_iterator<int>’ has no member named ‘serialize’

因此,似乎boost / serialization / list.hpp不支持迭代器。然而,据我所知,将迭代器保存到某个列表项是totally legitimate,因为除非被删除,否则它们不会失效。有没有办法使用boost序列化这个迭代器?我需要编写自定义函数吗?我是否必须从std :: list返回自定义迭代器? (听起来特别难看......)

感谢您的任何见解。

1 个答案:

答案 0 :(得分:0)

好的,似乎唯一的方法是将序列化拆分为保存和加载,并计算列表中迭代器的位置。只要迭代器有效,这就可以工作。不幸的是,这意味着需要将一个指向列表的指针添加到结构中,这是我不想要的,但实际上在我的应用程序中我可以访问它,所以这对我来说不是问题。

class Stepper                                                                            
{                                                                                        
public:                                                                                  
  Stepper() {}                                                                           
  Stepper(const A& _a)                                                                   
    : a(&_a), p(a->i.size()>0 ? a->i.begin() : a->i.end()) {}                            

  const A* a;                                                                            
  std::list<int>::const_iterator p;                                                      

  void display() {                                                                       
    std::cout << "p: " << *p << std::endl;                                               
  }                                                                                      

  void step() { p++; }                                                                   

private:                                                                                 
  friend class boost::serialization::access;                                             

  template<class Archive>                                                                
  void save(Archive &ar, const unsigned int version) const                               
  {                                                                                      
    int d = std::distance(a->i.begin(), p);                                              
    ar & a;                                                                              
    ar & d;                                                                              
  }                                                                                      

  template<class Archive>                                                                
  void load(Archive &ar, const unsigned int version)                                     
  {                                                                                      
    int d;                                                                               
    ar & a;                                                                              
    ar & d;                                                                              
    p = a->i.begin();                                                                    
    for (; d>0; --d)                                                                     
      p++;                                                                               
  }                                                                                      

  BOOST_SERIALIZATION_SPLIT_MEMBER()                                                     
};