使用命名值对(nvp)反序列化多态类型时的“cereal :: Exception”

时间:2016-03-18 10:02:11

标签: c++ inheritance polymorphism cereal

我正在收到一条“grain :: Exception”,其中包含以下消息:“JSON解析失败 - 在找到序列化命名值对的多态类反序列化时未提供NVP”。 我做错了吗?

这是标题:

#ifndef SERIALIZATION_H
#define SERIALIZATION_H

struct ComflabulationBase {
    ComflabulationBase(float thingy = 0.0f, int dingy = 0.0f, bool mingy = false, const std::string& stringy = "") : thingy(thingy), dingy(dingy), mingy(mingy), stringy(stringy) {}
    float thingy;
    int dingy;
    bool mingy;
    std::string stringy;

    template <class Archive>
    void serialize(Archive & ar)
    {
        ar(
            CEREAL_NVP(thingy),
            CEREAL_NVP(dingy),
            CEREAL_NVP(mingy),
            CEREAL_NVP(stringy)
          );
    }
    virtual ~ComflabulationBase() {}
    virtual void sayType() { std::cout << "Base" << std::endl; }
};

struct Vector3
{
    float x{0};
    float y{0};
    float z{0};

    template <class Archive>
    void serialize(Archive & ar)
    {
        ar(
            CEREAL_NVP(x),
            CEREAL_NVP(y),
            CEREAL_NVP(z)
          );
    }
};

struct Comflabulation : public ComflabulationBase
{
    Comflabulation(float bazingy = 1.5f, Vector3 vingy = Vector3()) : bazingy(bazingy), vingy(vingy) {}
    ~Comflabulation() {}
    float bazingy;
    Vector3 vingy;

    template <class Archive>
    void serialize(Archive & ar)
    {
        ar( cereal::base_class<ComflabulationBase>( this ),
            CEREAL_NVP(bazingy),
            CEREAL_NVP(vingy)
          );
    }

    void sayType() {std::cout << "Derived" << std::endl; }

};
CEREAL_REGISTER_TYPE(Comflabulation)

#endif // SERIALIZATION_H

和我的cpp文件:

#include "cereal/cereal.hpp"
#include "cereal/archives/binary.hpp"
#include "cereal/archives/json.hpp"
#include "cereal/types/polymorphic.hpp"
#include <sstream>

#include "serialization.h"


template<typename T, typename ...Args>
std::unique_ptr<T> make_unique( Args&& ...args )
{
    return std::unique_ptr<T>( new T( std::forward<Args>(args)... ) );
}

int main (void)
{
    std::stringstream ss;

    {
        std::unique_ptr<Comflabulation> one = make_unique<Comflabulation>();
        std::unique_ptr<Comflabulation> two = make_unique<Comflabulation>(3.0f);
        std::unique_ptr<Comflabulation> three = make_unique<Comflabulation>();
        cereal::JSONOutputArchive oarchive(ss);
        oarchive(one, two, three);
    }

    std::cout << ss.str() << std::endl;

    {
       std::unique_ptr<ComflabulationBase> one, two, three;
       cereal::JSONInputArchive iarchive(ss);
       iarchive(two, one, three);
       two->sayType();
    }


    std::cout << ss.str() << std::endl;

    return 0;
}

1 个答案:

答案 0 :(得分:0)

似乎你需要序列化一个指向多态基类的智能指针(参见http://uscilab.github.io/cereal/polymorphism.html):

std::unique_ptr<ComflabulationBase> one = make_unique<Comflabulation>();
std::unique_ptr<ComflabulationBase> two = make_unique<Comflabulation>(3.0f);
std::unique_ptr<ComflabulationBase> three = make_unique<Comflabulation>();

感谢Manuel Schiller指出这一点。