【问题标题】:Serialization of derived class from templated class versioning从模板类版本控制派生类的序列化
【发布时间】:2020-02-06 15:46:41
【问题描述】:

我正在尝试序列化从模板类派生的类,我在其中修复了模板参数。我想独立于派生类序列化基类,以防我将模板固定为其他类型,并且我希望派生类序列化为基类和一些其他数据。当我在我的最小示例中这样做时:

#include <iostream>
#include <sstream>
#include <boost/serialization/split_member.hpp>
#include <boost/serialization/traits.hpp>
#include <boost/serialization/level.hpp>
#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/text_iarchive.hpp>

using namespace boost::archive;
static constexpr unsigned int base_version = 1;

template<typename T>
struct Base : public boost::serialization::traits<Base<T>,
                                                 boost::serialization::object_class_info,
                                                 boost::serialization::track_never,
                                                 base_version> {
  T t;
  template<typename A>
  void load(A& a,
            unsigned int const in_version) {
    std::cerr << "Loading Base with version " << in_version  << std::endl;
    a & t;
  }
  template<typename A>
  void save(A& a,
            unsigned int const) const {
    std::cerr << "Saving Base with version " << base_version << std::endl;
    a & t;
  }
  BOOST_SERIALIZATION_SPLIT_MEMBER()
};

struct Derived : public Base<int> {
  int j;
  static constexpr unsigned int version = 2;
  template<typename A>
  void load(A& a,
            unsigned int const in_version) {
    std::cerr << "Loading Derived with version " << in_version << std::endl;
    a & boost::serialization::base_object<Base>(*this);
    a & j;
  }
  template<typename A>
  void save(A& a,
            unsigned int const) const {
    std::cerr << "Saving Derived with version " << version << std::endl;
    a & boost::serialization::base_object<Base>(*this);
    a & j;
  }
  BOOST_SERIALIZATION_SPLIT_MEMBER()
};
BOOST_CLASS_VERSION(Derived,Derived::version)

int main() {
  Derived d;
  d.t = 1;

  std::stringstream s;
  text_oarchive oa {s};
  oa << d;

  Derived e;
  text_iarchive ia{s};
  ia >> e;
  std::cerr << e.t << std::endl;

  return 0;
}

我得到一个输出:

Saving Derived with version 2
Saving Base with version 1
Loading Derived with version 2
Loading Base with version 2
1

似乎保存是使用正确的版本完成的,而加载总是使用派生类的版本完成的。这段代码有什么问题?

【问题讨论】:

    标签: c++ serialization boost versioning


    【解决方案1】:

    不是通过继承定义 Base 的版本,而是通过专门化 boost::serialization 命名空间的成员来定义我想要的行为:

    // headers as before
    #define BOOST_CLASS_TEMPLATE_VERSION(Template, Type, Version) \
    namespace boost {                                           \
      namespace serialization {                                 \
        template<Template>                                      \
        struct version<Type> {                                  \
          static constexpr unsigned int value = Version;        \
        };                                                      \
        template<Template>                                      \
        constexpr unsigned int version<Type>::value;            \
      }                                                         \
    }
    
    using namespace boost::archive;
    static constexpr unsigned int base_version = 1;
    
    template<typename T>
    struct Base {
      T t;
    // ...
    };
    BOOST_CLASS_TEMPLATE_VERSION(typename T, Base<T>, base_version);
    // rest as before
    

    给予

    $ ./main 
    Saving Derived with version 2
    Saving Base with version 1
    Loading Derived with version 2
    Loading Base with version 1
    1
    

    使用 Boost 1.67。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-09-23
      • 1970-01-01
      • 1970-01-01
      • 2018-01-22
      • 2010-11-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多