Reputation: 391
I have a templated base class:
template<typename T>
class A {
public:
T a;
template<class Archive>
void serialize(Archive & ar) {
ar(a);
}
};
and a templated class that derives from it:
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);
}
};
It is used in another serialized class:
template<typename T>
class C {
template<class Archive>
void serialize(Archive & ar)
{
ar(collection);
}
std::vector<std::shared_ptr<A<T>>> collection;
};
This code and the code that uses it is compiled into a static lib
From my understanding of the cereal docs I need to add
CEREAL_REGISTER_TYPE(A<double>)
CEREAL_REGISTER_TYPE(A<float>)
CEREAL_REGISTER_TYPE(B<double>)
CEREAL_REGISTER_TYPE(B<float>)
etc for each type that will be used, in the header files for each class
This compiles. But has a run time error of
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.
From the docs I think I need to add CEREAL_FORCE_DYNAMIC_INIT(libname)
in the headers and CEREAL_REGISTER_DYNAMIC_INIT
in the CPP file, but there is no cpp file. Or a suitable CPP file to place this in.
Adding CEREAL_REGISTER_POLYMORPHIC_RELATION
makes no difference as expected as B
's serialization function is calling the base calss A
with cereal::base_class
Is there a way to use Cereal to serialize templated classes?
Upvotes: 6
Views: 3540
Reputation: 391
Issue came down to the order of the included headers and where they were included, plus a small amount of RTFM carefully.
In base class header needed:
#include <cereal/types/polymorphic.hpp>
#include <cereal/archives/portable_binary.hpp>
plus any other types I want to serialize to.
Then in subclasses add CEREAL_REGISTER_TYPE
for each supported type.
The key, as noted in the documentation, is that the type of archive is included BEFORE CEREAL_REGISTER_TYPE
. They do not have to be in the same file as the class declaration. Just include headers before registering types.
Upvotes: 6