Я использую зерновой библиотека и пытаюсь получить экземпляр 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;
}
Мой тип «Size» сериализуется правильно. Я также включаю cereal / types / memory.hpp, cereal / types / map.hpp, cereal / types / string.hpp и cereal / types / base_class.hpp, но когда я пытаюсь запустить вышеуказанный тест для FileTextureDefinition, я получаю следующая ошибка:
1>C:\git\external\cereal\include\cereal/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:\git\external\cereal\include\cereal/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:\git\external\cereal\include\cereal/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:\git\external\cereal\include\cereal/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:\git\external\cereal\include\cereal/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:\git\external\cereal\include\cereal/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:\git\external\cereal\include\cereal/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:\git\external\cereal\include\cereal/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:\git\external\cereal\include\cereal/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:\git\external\cereal\include\cereal/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:\git\external\cereal\include\cereal/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:\git\external\cereal\include\cereal/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:\git\wargameclient\source\game.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:\git\wargameclient\source\game.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 вы должны специально регистрировать свои типы. Это было решено для меня, добавив следующие три строки в мой файл textures.cpp и включив «cereal / types / polymorphic.hpp»:
CEREAL_REGISTER_TYPE(MV::FileTextureDefinition);
CEREAL_REGISTER_TYPE(MV::DynamicTextureDefinition);
CEREAL_REGISTER_TYPE(MV::SurfaceTextureDefinition);
Других решений пока нет …