I have a problem with cereal library (http://uscilab.github.io/cereal/).
I have a shared library, and I would like to serialize one of its classes using cereal library. It has a member of time_point from std::chrono
Here is a part of the code of my object in Event.h
#include <cereal/types/chrono.hpp>
#include <cereal/types/string.hpp>
class Event
{
private:
std::string m_Id;
std::chrono::high_resolution_clock::time_point m_StartTime;
public:
template<class Archive> void serialize(Archive & archive)
{
archive(m_Id, m_StartTime);
}
The library compiles without a problem. Then I would like to use my library in an executable where I try to serialize one of the object:
#include "Event.h"
#include <cereal/archives/json.hpp>
cereal::JSONOutputArchive output(std::cout);
output(API::Event());
This code does not compile and it is complaining about the missing serialize function for the time_point. If I intend to serialize only the string it compiles.
Build error output:
[ 20%] Building CXX object CMakeFiles/plugin.dir/src/main.cpp.o
In file included from /cereal/include/cereal/types/memory.hpp:33:0,
from main.cpp:7:
cereal/include/cereal/cereal.hpp: In instantiation of ‘ArchiveType&
cereal::OutputArchive<ArchiveType, Flags>::processImpl(const T&) [with T = std::chrono::time_point<std::chrono::_V2::system_clock, std::chrono::duration<long int, std::ratio<1, 1000000000> > >; typename cereal::traits::detail::EnableIfHelper<(cereal::traits::has_invalid_output_versioning<T, ArchiveType>::value || ((! cereal::traits::is_output_serializable<T, ArchiveType>::value) && ((!(Flags & AllowEmptyClassElision)) || ((Flags & AllowEmptyClassElision) && (! std::is_empty<T>::value)))))>::type <anonymous> = (cereal::traits::detail::type)0; ArchiveType = cereal::JSONOutputArchive; unsigned int Flags = 0]’:
cereal/include/cereal/cereal.hpp:347:9: required from ‘void cereal::OutputArchive<ArchiveType, Flags>::process(T&&) [with T = std::chrono::time_point<std::chrono::_V2::system_clock, std::chrono::duration<long int, std::ratio<1, 1000000000> > >&; ArchiveType = cereal::JSONOutputArchive; unsigned int Flags = 0]’
cereal/include/cereal/cereal.hpp:249:9: required from ‘ArchiveType& cereal::OutputArchive<ArchiveType, Flags>::operator()(Types&& ...) [with Types = {std::chrono::time_point<std::chrono::_V2::system_clock, std::chrono::duration<long int, std::ratio<1, 1000000000> > >&}; ArchiveType = cereal::JSONOutputArchive; unsigned int Flags = 0]’
Event.h:66:16: required from ‘void Event::serialize(Archive&) [with Archive = cereal::JSONOutputArchive]’
cereal/include/cereal/access.hpp:243:51: required from ‘static decltype (t.serialize(ar)) cereal::access::member_serialize(Archive&, T&) [with Archive = cereal::JSONOutputArchive; T = Event; decltype (t.serialize(ar)) = void]’
cereal/include/cereal/cereal.hpp:400:33: required from ‘ArchiveType& cereal::OutputArchive<ArchiveType, Flags>::processImpl(const T&) [with T = Event; typename cereal::traits::detail::EnableIfHelper<cereal::traits::has_member_serialize<T, ArchiveType>::value, (! cereal::traits::has_invalid_output_versioning<T, ArchiveType>::value), (cereal::traits::is_output_serializable<T, ArchiveType>::value && (cereal::traits::is_specialized_member_serialize<T, ArchiveType>::value || (! cereal::traits::is_specialized<T, ArchiveType>::value)))>::type <anonymous> = (cereal::traits::detail::type)0; ArchiveType = cereal::JSONOutputArchive; unsigned int Flags = 0]’
cereal/include/cereal/cereal.hpp:347:9: required from ‘void cereal::OutputArchive<ArchiveType, Flags>::process(T&&) [with T = Event; ArchiveType = cereal::JSONOutputArchive; unsigned int Flags = 0]’
cereal/include/cereal/cereal.hpp:249:9: required from ‘ArchiveType& cereal::OutputArchive<ArchiveType, Flags>::operator()(Types&& ...) [with Types = {Event}; ArchiveType = cereal::JSONOutputArchive; unsigned int Flags = 0]’
main.cpp:38:36: required from here
cereal/include/cereal/cereal.hpp:462:9: error: static assertion failed: cereal could not find any output serialization functions for the provided type and archive combination.
EDIT:
I guess the problem is coming from the fact that the serialization function is defined in the shared library.
If I just compile a test class (not in my project just for test) having an time_point it works as expected.
It looks like it was due to the order of the include. The include of the archives must be before the include of the types/chrono. So the right order is:
#include <cereal/archives/json.hpp>
#include "Event.h"
cereal::JSONOutputArchive output(std::cout);
output(API::Event());