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)ドキュメントから、ヘッダーとCPP ファイルに追加する必要があると思いCEREAL_REGISTER_DYNAMIC_INITますが、cpp ファイルはありません。または、これを配置する適切な CPP ファイル。

CEREAL_REGISTER_POLYMORPHIC_RELATIONのシリアライゼーションB関数はAIs cereal::base_class there a way to use Cereal to serialize templated classes?

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 に答える