Search code examples
c++c++11serializationcereal

Cereal serialization


I have a problem in C++11 with cereal (http://uscilab.github.io/cereal/).

I have a shared library, and I would like to serialize one of its classes using cereal library. Here is a part of the code of the library "I would like to serialize Object class":

"Object.hpp"

class ObjectPrivate;

class Object
{
 public:
    ...
    template <class Archive>
    void load(Archive& archive);

    template <class Archive>
    void save(Archive& archive) const;

 protected: 
    std::unique_ptr<ObjectPrivate> d_ptr;
};

template<>
void Object::load<cereal::BinaryInputArchive>(cereal::BinaryInputArchive& archive);

template<>
void Object::save<cereal::BinaryOutputArchive>(cereal::BinaryOutputArchive& archive) const;

"Object.cpp"

#include"Object_p.hpp"
template <class Archive>
void Object::load(Archive& archive)
{
    archive(d_ptr);
}

template <class Archive>
void Object::save(Archive& archive) const
{
    archive(d_ptr);
}

"Object_p.hpp"

#include"Object.hpp"

class ObjectPrivate
{
 public:
    int m_id;

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

but I got an error:

error: undefined reference to void GraphicalObject::save<cereal::BinaryOutputArchive>(cereal::BinaryOutputArchive&) const
error: undefined reference to void GraphicalObject::load<cereal::BinaryInputArchive>(cereal::BinaryInputArchive&)

Solution

  • CS Pei is right, I forgot the implementation of the functions:

    template<>
    void Object::load<cereal::BinaryInputArchive>(cereal::BinaryInputArchive& archive);
    
    template<>
    void Object::save<cereal::BinaryOutputArchive>(cereal::BinaryOutputArchive& archive) const;
    

    The right implementation:

    "Object.hpp"

    class ObjectPrivate;
    
    class Object
    {
     public:
        ...
        template <class Archive>
        void load(Archive& archive);
    
        template <class Archive>
        void save(Archive& archive) const;
    
     protected: 
        std::unique_ptr<ObjectPrivate> d_ptr;
    };
    
    template<>
    void Object::load<cereal::BinaryInputArchive>(cereal::BinaryInputArchive& archive);
    
    template<>
    void Object::save<cereal::BinaryOutputArchive>(cereal::BinaryOutputArchive& archive) const;
    

    "Object.cpp"

    #include"Object_p.hpp"
    template <class Archive>
    void Object::load(Archive& archive)
    {
        archive(d_ptr->m_id);
    }
    
    template <class Archive>
    void Object::save(Archive& archive) const
    {
        archive(d_ptr->m_id);
    }
    
    template <>
    void GraphicalObject::save<cereal::BinaryOutputArchive>(cereal::BinaryOutputArchive& archive) const
    {
        archive(d_ptr->m_id);
    }
    
    template <>
    void GraphicalObject::load<cereal::BinaryInputArchive>(cereal::BinaryInputArchive& archive)
    {
        archive(d_ptr->m_id);
    }
    

    "Object_p.hpp"

    #include"Object.hpp"
    
    class ObjectPrivate
    {
     public:
        int m_id;
    };