从模板化类版本控制序列化派生类



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

#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

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

定义 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

与提升 1.67。

最新更新