6

我有一个模板化的基类:

template<typename T>
class A {
    public:
    T a;

    template<class Archive>
    void serialize(Archive & ar) {
        ar(a);
    }
};

以及从它派生的模板类:

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

它在另一个序列化类中使用:

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>)

等将使用的每种类型,在每个类的头文件中

这编译。但有一个运行时错误

试图保存未注册的多态类型 (B)。在调用 CEREAL_REGISTER_TYPE 之前,请确保您的类型已向 CEREAL_REGISTER_TYPE 注册,并且您正在使用的存档已包含(并已向 CEREAL_REGISTER_ARCHIVE 注册)。如果您的类型已经注册并且您仍然看到此错误,您可能需要使用 CEREAL_REGISTER_DYNAMIC_INIT。

从文档中我认为我需要CEREAL_FORCE_DYNAMIC_INIT(libname)在标题和CEREAL_REGISTER_DYNAMIC_INITCPP 文件中添加,但没有 cpp 文件。或者一个合适的 CPP 文件来放置它。

正如预期的那样,添加CEREAL_REGISTER_POLYMORPHIC_RELATION没有任何区别,因为B's 的序列化函数正在调用基类Acereal::base_class 有没有办法使用 Cereal 序列化模板类?

4

1 回答 1

6

问题归结为包含标题的顺序和包含它们的位置,以及少量的 RTFM。

在需要的基类头文件中:

#include <cereal/types/polymorphic.hpp>
#include <cereal/archives/portable_binary.hpp>

加上我想序列化的任何其他类型。

然后在子类CEREAL_REGISTER_TYPE中为每个支持的类型添加。

如文档中所述,关键是归档类型包含在 BEFORE CEREAL_REGISTER_TYPE中。它们不必与类声明在同一个文件中。只需在注册类型之前包含标题。

于 2016-10-20T17:44:21.257 回答