麦片系列化

Cereal serialization

我在 C++11 中遇到谷物问题 (http://uscilab.github.io/cereal/)。

我有一个共享库,我想使用谷物库序列化其中一个 类。这是库 "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);
    }
};

但是我得到一个错误:

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

您声明了模板的两个特化,

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

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

但是你忘了实现它们。

CS Pei说的对,函数的实现忘记了:

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

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

正确的实现:

"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;
};