C++11 谷物库无法序列化我的一类

C++11 Cereal Library Cannot Serialize A Class Of Mine

本文关键字:一类 我的 序列化 C++11      更新时间:2023-10-16

我正在使用谷物库,并试图获取具有自定义构造函数的派生类型的shared_ptr实例,以正确输入存档。 我已经倾注了以下文档,但显然遗漏了一些东西。

以下是我的继承制中的类:

class TextureDefinition : public std::enable_shared_from_this<TextureDefinition> {
    template <class Archive>
    friend void serialize(Archive & archive, TextureDefinition & texture);
public:
    virtual ~TextureDefinition(){}
    std::shared_ptr<TextureHandle> makeHandle();
    std::shared_ptr<TextureHandle> makeHandle(const Point<int> &a_position, const Size<int> &a_size);
    void setOnReload(std::function< void (std::shared_ptr<TextureDefinition>) > a_onReload);
    void clearOnReload();
    GLuint textureId() const;
    std::string name() const;
    Size<int> size() const;
    //bookkeeping
    void reload();
    void cleanup();
protected:
    TextureDefinition(const std::string &a_name);
    std::string textureName;
    Size<int> textureSize;
    GLuint texture;
    std::vector< std::weak_ptr<TextureHandle> > handles;
private:
    virtual void reloadImplementation() = 0;
    virtual void cleanupImplementation(){}
    std::function< void (std::shared_ptr<TextureDefinition>) > onReload;
};
template <class Archive>
void serialize(Archive & archive, TextureDefinition &texture){
    archive(cereal::make_nvp("name", texture.name()), cereal::make_nvp("size", texture.size()));// , cereal::make_nvp("handles", handles)); //not saving handles right now to simplify testing.
}
class FileTextureDefinition : public TextureDefinition {
public:
    static std::shared_ptr<FileTextureDefinition> make(const std::string &a_filename, bool a_repeat = false){
        return std::shared_ptr<FileTextureDefinition>(new FileTextureDefinition(a_filename, a_repeat));
    }
    template <class Archive>
    static FileTextureDefinition * load_and_allocate(Archive &ar){
        return new FileTextureDefinition("", false);
    }
    template <class Archive>
    void serialize(Archive & archive){
        archive(cereal::base_class<TextureDefinition>(this), CEREAL_NVP(repeat));
        if(!handles.empty()){
            reload();
        }
    }
private:
    FileTextureDefinition(const std::string &a_filename, bool a_repeat):
        TextureDefinition(a_filename),
        repeat(a_repeat){
    }
    virtual void reloadImplementation();
    bool repeat;
};

这是我尝试运行的测试代码:

void saveTest(){
    std::stringstream stream;
    {
        cereal::JSONOutputArchive archive(stream);
        auto testSave = MV::FileTextureDefinition::make("test.png");
        archive(cereal::make_nvp("test", testSave));
    }
    std::cout << stream.str() << std::endl;
}

我的"大小"类型确实正确序列化。 我还包括 cereal/types/memory.hpp、cereal/types/map.hpp、cereal/types/string.hpp 和 cereal/types/base_class.hpp,但是当我尝试运行上述 FileTextureDefinition 测试时,出现以下错误:

1>C:gitexternalcerealincludecereal/cereal.hpp(432): error C2338: Trying to serialize an unserializable type with an output archive.
1>  
1>  Types must either have a serialize function, or separate save/load functions (but not both). 
1>  In addition, you may not mix versioned with non-versioned serialization functions. 
1>  Serialize functions generally have the following signature: 
1>  
1>  template<class Archive> 
1>    void serialize(Archive & ar)
1>    {
1>      ar( member1, member2, member3 );
1>    }
1>  
1>  
1>          C:gitexternalcerealincludecereal/cereal.hpp(329) : see reference to function template instantiation 'cereal::JSONOutputArchive &cereal::OutputArchive<cereal::JSONOutputArchive,0>::processImpl<std::shared_ptr<MV::FileTextureDefinition>>(const T &)' being compiled
1>          with
1>          [
1>              T=std::shared_ptr<MV::FileTextureDefinition>
1>          ]
1>          C:gitexternalcerealincludecereal/cereal.hpp(329) : see reference to function template instantiation 'cereal::JSONOutputArchive &cereal::OutputArchive<cereal::JSONOutputArchive,0>::processImpl<std::shared_ptr<MV::FileTextureDefinition>>(const T &)' being compiled
1>          with
1>          [
1>              T=std::shared_ptr<MV::FileTextureDefinition>
1>          ]
1>          C:gitexternalcerealincludecereal/cereal.hpp(245) : see reference to function template instantiation 'void cereal::OutputArchive<cereal::JSONOutputArchive,0>::process<std::shared_ptr<MV::FileTextureDefinition>&>(T)' being compiled
1>          with
1>          [
1>              T=std::shared_ptr<MV::FileTextureDefinition> &
1>          ]
1>          C:gitexternalcerealincludecereal/cereal.hpp(245) : see reference to function template instantiation 'void cereal::OutputArchive<cereal::JSONOutputArchive,0>::process<std::shared_ptr<MV::FileTextureDefinition>&>(T)' being compiled
1>          with
1>          [
1>              T=std::shared_ptr<MV::FileTextureDefinition> &
1>          ]
1>          C:gitexternalcerealincludecereal/archives/json.hpp(711) : see reference to function template instantiation 'ArchiveType &cereal::OutputArchive<ArchiveType,0>::operator ()<_Ty&>(_Ty &)' being compiled
1>          with
1>          [
1>              ArchiveType=cereal::JSONOutputArchive
1>  ,            _Ty=std::shared_ptr<MV::FileTextureDefinition>
1>          ]
1>          C:gitexternalcerealincludecereal/archives/json.hpp(711) : see reference to function template instantiation 'ArchiveType &cereal::OutputArchive<ArchiveType,0>::operator ()<_Ty&>(_Ty &)' being compiled
1>          with
1>          [
1>              ArchiveType=cereal::JSONOutputArchive
1>  ,            _Ty=std::shared_ptr<MV::FileTextureDefinition>
1>          ]
1>          C:gitexternalcerealincludecereal/cereal.hpp(404) : see reference to function template instantiation 'void cereal::save<std::shared_ptr<MV::FileTextureDefinition>&>(cereal::JSONOutputArchive &,const cereal::NameValuePair<std::shared_ptr<MV::FileTextureDefinition> &> &)' being compiled
1>          C:gitexternalcerealincludecereal/cereal.hpp(329) : see reference to function template instantiation 'cereal::JSONOutputArchive &cereal::OutputArchive<cereal::JSONOutputArchive,0>::processImpl<T>(const T &)' being compiled
1>          with
1>          [
1>              T=cereal::NameValuePair<std::shared_ptr<MV::FileTextureDefinition> &>
1>          ]
1>          C:gitexternalcerealincludecereal/cereal.hpp(329) : see reference to function template instantiation 'cereal::JSONOutputArchive &cereal::OutputArchive<cereal::JSONOutputArchive,0>::processImpl<T>(const T &)' being compiled
1>          with
1>          [
1>              T=cereal::NameValuePair<std::shared_ptr<MV::FileTextureDefinition> &>
1>          ]
1>          C:gitexternalcerealincludecereal/cereal.hpp(245) : see reference to function template instantiation 'void cereal::OutputArchive<cereal::JSONOutputArchive,0>::process<_Ty>(T &&)' being compiled
1>          with
1>          [
1>              _Ty=cereal::NameValuePair<std::shared_ptr<MV::FileTextureDefinition> &>
1>  ,            T=cereal::NameValuePair<std::shared_ptr<MV::FileTextureDefinition> &>
1>          ]
1>          C:gitexternalcerealincludecereal/cereal.hpp(245) : see reference to function template instantiation 'void cereal::OutputArchive<cereal::JSONOutputArchive,0>::process<_Ty>(T &&)' being compiled
1>          with
1>          [
1>              _Ty=cereal::NameValuePair<std::shared_ptr<MV::FileTextureDefinition> &>
1>  ,            T=cereal::NameValuePair<std::shared_ptr<MV::FileTextureDefinition> &>
1>          ]
1>          c:gitwargameclientsourcegame.h(49) : see reference to function template instantiation 'ArchiveType &cereal::OutputArchive<ArchiveType,0>::operator ()<cereal::NameValuePair<std::shared_ptr<MV::FileTextureDefinition> &>>(cereal::NameValuePair<std::shared_ptr<MV::FileTextureDefinition> &> &&)' being compiled
1>          with
1>          [
1>              ArchiveType=cereal::JSONOutputArchive
1>          ]
1>          c:gitwargameclientsourcegame.h(49) : see reference to function template instantiation 'ArchiveType &cereal::OutputArchive<ArchiveType,0>::operator ()<cereal::NameValuePair<std::shared_ptr<MV::FileTextureDefinition> &>>(cereal::NameValuePair<std::shared_ptr<MV::FileTextureDefinition> &> &&)' being compiled
1>          with
1>          [
1>              ArchiveType=cereal::JSONOutputArchive
1>          ]

textures.h 头文件的完整链接可以在 pastebin 上找到,但我已经包含了我认为是相关部分的内容。

啊哈! 所以问题很简单。 我习惯于自动处理多态性,但是对于 Cereal,您必须专门注册您的类型。 通过向我的纹理.cpp文件添加以下三行并包括"谷物/类型/polymorphic.hpp",为我解决了这个问题:

CEREAL_REGISTER_TYPE(MV::FileTextureDefinition);
CEREAL_REGISTER_TYPE(MV::DynamicTextureDefinition);
CEREAL_REGISTER_TYPE(MV::SurfaceTextureDefinition);