麦片序列化错误

Cereal serialization error

所以我很困惑。它不会为外部序列化函数编译。它给出了错误

cereal could not find any output serialization functions for the provided type and archive combination.

所以下面的代码无法编译

#include <fstream>
#include <glm/glm.hpp>
#include "SceneObject.h"
#include <cereal/cereal.hpp>
#include <cereal/archives/json.hpp>

template<typename Archive> void serialize(Archive& archive, glm::vec3& v3)
{
    archive(cereal::make_nvp("x", v3.x), cereal::make_nvp("y", v3.y), cereal::make_nvp("z", v3.z));
}

struct something
{
public:
    float x, y, z;
};
template<typename Archive> void serialize(Archive& archive, something& v3)
{
    archive(cereal::make_nvp("x", v3.x), cereal::make_nvp("y", v3.y), cereal::make_nvp("z", v3.z));
}

int main(int argc, char** argv)
{
    SceneObject test;
    test.transform().setPosition(1.0f,2.0f,3.0f);

    {
        std::ofstream file("TestPath.json");
        cereal::JSONOutputArchive output(file);
        glm::vec3 p = test.transform().getPosition();
        output(p);
    }

    return 0;
}

但这确实编译

#include <fstream>
#include <glm/glm.hpp>
#include "SceneObject.h"
#include <cereal/cereal.hpp>
#include <cereal/archives/json.hpp>

template<typename Archive> void serialize(Archive& archive, glm::vec3& v3)
{
    archive(cereal::make_nvp("x", v3.x), cereal::make_nvp("y", v3.y), cereal::make_nvp("z", v3.z));
}

struct something
{
public:
    float x, y, z;
};
template<typename Archive> void serialize(Archive& archive, something& v3)
{
    archive(cereal::make_nvp("x", v3.x), cereal::make_nvp("y", v3.y), cereal::make_nvp("z", v3.z));
}

int main(int argc, char** argv)
{
    SceneObject test;
    test.transform().setPosition(1.0f,2.0f,3.0f);

    {
        std::ofstream file("TestPath.json");
        cereal::JSONOutputArchive output(file);
        glm::vec3 p = test.transform().getPosition();
        something s;
        s.x = p.x;
        s.y = p.y;
        s.z = p.z;
        output(s);
    }

    return 0;
}

我直接将 glm::vec3 中的保存代码复制并粘贴到某个地方,然后将 glm::vec3 更改为 'something'。对我来说,为什么它适用于一个而不适用于另一个对我来说毫无意义。我认为这可能是命名空间的问题,但我不知道如何解决它。

很明显发帖让我找到了解决方案。

您需要确保序列化函数共享相同的命名空间,所以如果我将它们包装成

namespace glm
{
template<typename Archive> void serialize(Archive& archive, glm::vec3& v3)
{
    archive(cereal::make_nvp("x", v3.x), cereal::make_nvp("y", v3.y),    cereal::make_nvp("z", v3.z));
}
}

有效。有点奇怪,但事实就是如此。

我可以证实你的结论。在外部定义的情况下 serialize-functions 你可以将它们放在同一个命名空间中以使谷物能够 see/use 它们。

a complete/templated 一组 serialization-functions for all flavor of vec2-4, mat2-4 and quat types can be each this (requires glm-version >=0.9.6, https://www.g-truc.net/post-0693.html):

#include <glm/glm.hpp>
#include <cereal/cereal.hpp>

namespace glm
{

template<class Archive, class T>
void serialize(Archive &archive, glm::vec<2, T, glm::defaultp> &v)
{
    archive(cereal::make_nvp("x", v.x),
            cereal::make_nvp("y", v.y));
}

template<class Archive, class T>
void serialize(Archive &archive, glm::vec<3, T, glm::defaultp> &v)
{
    archive(cereal::make_nvp("x", v.x),
            cereal::make_nvp("y", v.y),
            cereal::make_nvp("z", v.z));
}

template<class Archive, class T>
void serialize(Archive &archive, glm::vec<4, T, glm::defaultp> &v)
{
    archive(cereal::make_nvp("x", v.x),
            cereal::make_nvp("y", v.y),
            cereal::make_nvp("z", v.z),
            cereal::make_nvp("w", v.w));
}

// glm matrices serialization
template<class Archive, class T>
void serialize(Archive &archive, glm::mat<2, 2, T, glm::defaultp> &m){ archive(m[0], m[1]); }

template<class Archive, class T>
void serialize(Archive &archive, glm::mat<3, 3, T, glm::defaultp> &m){ archive(m[0], m[1], m[2]); }

template<class Archive, class T>
void serialize(Archive &archive, glm::mat<4, 4, T, glm::defaultp> &m){ archive(m[0], m[1], m[2], m[3]); }

template<class Archive, class T>
void serialize(Archive &archive, glm::qua<T, glm::defaultp> &q)
{
    archive(cereal::make_nvp("x", q.x),
            cereal::make_nvp("y", q.y),
            cereal::make_nvp("z", q.z),
            cereal::make_nvp("w", q.w));
}

}// namespace glm