使用 Cereal 序列化库中的模板化多态类型
Using Cereal to serialize templated polymorphic types in a library
我有一个模板化的基础class:
template<typename T>
class A {
public:
T a;
template<class Archive>
void serialize(Archive & ar) {
ar(a);
}
};
以及从中派生的模板化 class:
template<typename T>
class B : public A<T> {
public:
T b;
template<class Archive>
void serialize(Archive & ar) {
ar(cereal::base_class<A<T>>(this));
ar(b);
}
};
用于另一个连载class:
template<typename T>
class C {
template<class Archive>
void serialize(Archive & ar)
{
ar(collection);
}
std::vector<std::shared_ptr<A<T>>> collection;
};
这段代码和使用它的代码被编译成一个静态库
根据我对谷物文档的理解,我需要添加
CEREAL_REGISTER_TYPE(A<double>)
CEREAL_REGISTER_TYPE(A<float>)
CEREAL_REGISTER_TYPE(B<double>)
CEREAL_REGISTER_TYPE(B<float>)
etc 对于将要使用的每种类型,在每个 class
的 header 文件中
这编译。但是 运行 的时间误差为
Trying to save an unregistered polymorphic type (B). Make sure
your type is registered with CEREAL_REGISTER_TYPE and that the archive
you are using was included (and registered with
CEREAL_REGISTER_ARCHIVE) prior to calling CEREAL_REGISTER_TYPE. If
your type is already registered and you still see this error, you may
need to use CEREAL_REGISTER_DYNAMIC_INIT.
从文档中我认为我需要在 header 中添加 CEREAL_FORCE_DYNAMIC_INIT(libname)
并在 CPP 文件中添加 CEREAL_REGISTER_DYNAMIC_INIT
,但是没有 cpp 文件。或者一个合适的 CPP 文件来放置它。
添加 CEREAL_REGISTER_POLYMORPHIC_RELATION
并没有像预期的那样产生任何影响,因为 B
的序列化函数正在使用 cereal::base_class
调用基础调用 A
有没有办法使用 Cereal 序列化模板化 classes?
问题归结为包含的 header 的顺序和包含它们的位置,加上少量的 RTFM。
基础 class header 需要:
#include <cereal/types/polymorphic.hpp>
#include <cereal/archives/portable_binary.hpp>
加上我想要序列化的任何其他类型。
然后在 subclasses 中为每个支持的类型添加 CEREAL_REGISTER_TYPE
。
如文档中所述,关键是存档类型包含在 BEFORECEREAL_REGISTER_TYPE
之前。它们不必与 class 声明位于同一文件中。只需在注册类型之前包含 headers。
我有一个模板化的基础class:
template<typename T>
class A {
public:
T a;
template<class Archive>
void serialize(Archive & ar) {
ar(a);
}
};
以及从中派生的模板化 class:
template<typename T>
class B : public A<T> {
public:
T b;
template<class Archive>
void serialize(Archive & ar) {
ar(cereal::base_class<A<T>>(this));
ar(b);
}
};
用于另一个连载class:
template<typename T>
class C {
template<class Archive>
void serialize(Archive & ar)
{
ar(collection);
}
std::vector<std::shared_ptr<A<T>>> collection;
};
这段代码和使用它的代码被编译成一个静态库
根据我对谷物文档的理解,我需要添加
CEREAL_REGISTER_TYPE(A<double>)
CEREAL_REGISTER_TYPE(A<float>)
CEREAL_REGISTER_TYPE(B<double>)
CEREAL_REGISTER_TYPE(B<float>)
etc 对于将要使用的每种类型,在每个 class
的 header 文件中这编译。但是 运行 的时间误差为
Trying to save an unregistered polymorphic type (B). Make sure your type is registered with CEREAL_REGISTER_TYPE and that the archive you are using was included (and registered with CEREAL_REGISTER_ARCHIVE) prior to calling CEREAL_REGISTER_TYPE. If your type is already registered and you still see this error, you may need to use CEREAL_REGISTER_DYNAMIC_INIT.
从文档中我认为我需要在 header 中添加 CEREAL_FORCE_DYNAMIC_INIT(libname)
并在 CPP 文件中添加 CEREAL_REGISTER_DYNAMIC_INIT
,但是没有 cpp 文件。或者一个合适的 CPP 文件来放置它。
添加 CEREAL_REGISTER_POLYMORPHIC_RELATION
并没有像预期的那样产生任何影响,因为 B
的序列化函数正在使用 cereal::base_class
调用基础调用 A
有没有办法使用 Cereal 序列化模板化 classes?
问题归结为包含的 header 的顺序和包含它们的位置,加上少量的 RTFM。
基础 class header 需要:
#include <cereal/types/polymorphic.hpp>
#include <cereal/archives/portable_binary.hpp>
加上我想要序列化的任何其他类型。
然后在 subclasses 中为每个支持的类型添加 CEREAL_REGISTER_TYPE
。
如文档中所述,关键是存档类型包含在 BEFORECEREAL_REGISTER_TYPE
之前。它们不必与 class 声明位于同一文件中。只需在注册类型之前包含 headers。