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?
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With