简体   繁体   English

有没有一种方法可以使用Boost序列化序列化迭代器?

[英]Is there a way to serialize iterators using boost serialization?

In my project I have a class containing and std::list and in another class I maintain an iterator pointing to a place in the middle of that list. 在我的项目中,我有一个包含and std :: list的类,在另一个类中,我维护了一个指向该列表中间位置的迭代器。

I can successfully serialize the list, but the iterator member variable is causing problems. 我可以成功序列化列表,但是迭代器成员变量引起了问题。 Here is a program to reproduce: 这是一个要重现的程序:

#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;
}

In this program, the class A can be serialized without problems. 在此程序中,可以毫无问题地对A类进行序列化。 (Remove the ar&sa stuff..) But unfortunately when trying to serialize the class containing the iterator (the exact code above), I get the following compilation errors: (删除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’

So, it seems that boost/serialization/list.hpp does not support iterators. 因此,似乎boost / serialization / list.hpp不支持迭代器。 And yet, as far as I can tell, it's totally legitimate to keep an iterator to a list item somewhere, as they cannot be invalidated unless erased. 但是,据我所知,将迭代器保留在某个列表项中是完全合法的 ,因为除非将其删除,否则它们不会无效。 Is there a way to serialize this iterator using boost? 有没有一种方法可以使用boost序列化此迭代器? Do I need to write a custom function? 我需要编写自定义函数吗? Do I have to return a custom iterator from my std::list? 我是否必须从std :: list返回自定义迭代器? (That sounds particularly ugly..) (听起来特别难看。)

Thanks for any insight. 感谢您的见解。

Okay it seems the only way to do this is to split the serialization into save and load, and calculate the iterator's position in the list. 好的,看来这样做的唯一方法是将序列化拆分为保存和加载,并计算迭代器在列表中的位置。 This works as long as the iterator is valid. 只要迭代器有效,它就起作用。 Unfortunately it means needing to add a pointer to the list to the structure, which I didn't want, but actually in my application I can access this so it is not a problem for me. 不幸的是,这意味着需要向结构添加指向列表的指针,这是我所不希望的,但是实际上,在我的应用程序中,我可以访问它,所以这对我来说不是问题。

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()                                                     
};

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM