【发布时间】:2019-01-05 20:50:34
【问题描述】:
我目前正在尝试使用静态函数创建一个可序列化的基类,以序列化和反序列化派生类对象。 我已阅读 Cereal Documentation for registering Polymorphic Relations 以及如何注册类型以及如何声明序列化函数。 目标是像这样使用 Serializable :
std::stringstream& ss Serializable::serialize(test);
我正在使用 Visual Studio 平台工具 2017(v141)。目标 Windows SDK 是 10.0.17134.0
但我无法构建我的应用程序并出现这 2 个错误 3 次:
Error C2338 cereal could not find any output serialization functions for the provided type and archive combination.
Error C2338 cereal could not find any input serialization functions for the provided type and archive combination.
这是我的代码:
可序列化的.hpp#pragma once
#include <string>
#include <cereal/archives/portable_binary.hpp>
class Serializable
{
public:
Serializable() = default;
~Serializable() = default;
virtual bool isAccessible() = 0;
static std::stringstream serialize(std::shared_ptr<Serializable> serializable);
static std::shared_ptr<Serializable> deserialize(std::stringstream& serialized);
};
可序列化的.cpp
#include "Serializable.hpp"
std::stringstream Serializable::serialize(std::shared_ptr<Serializable> serializable)
{
std::stringstream ss;
{
cereal::PortableBinaryOutputArchive ar(ss);
ar << serializable;
}
return ss;
}
std::shared_ptr<Serializable> Serializable::deserialize(std::stringstream& serialized)
{
cereal::PortableBinaryInputArchive ar(serialized);
std::shared_ptr<Serializable> result = nullptr;
ar >> result;
return result;
}
测试对象.hpp
#pragma once
#include "Serializable.hpp"
#include <string>
#include <cereal/types/string.hpp>
#include <cereal/types/polymorphic.hpp>
#include <cereal/types/base_class.hpp>
class TestObject : public Serializable
{
public:
TestObject() = default;
TestObject(const std::string& name);
~TestObject() = default;
std::string getName() const { return this->name; };
template<class Archive>
void serialize(Archive& ar)
{
ar(cereal::base_class<Serializable>(this), name);
};
virtual bool isAccessible() {
return true;
};
private:
std::string name;
};
CEREAL_REGISTER_TYPE(TestObject)
CEREAL_REGISTER_POLYMORPHIC_RELATION(Serializable,TestObject)
测试对象.cpp
#include "TestObject.hpp"
TestObject::TestObject(const std::string& name)
:TestObject(name){}
主文件
#include "TestObject.hpp"
#include "Serializable.hpp"
#include <memory>
#include <iostream>
#include <string>
int main(int argc, char **argv)
{
std::shared_ptr<Serializable> test(new TestObject("Test"));
auto ss = Serializable::serialize(test);
std::shared_ptr<Serializable> deserialized = Serializable::deserialize(ss);
auto test2 = dynamic_cast<TestObject*>(deserialized.get());
std::cout << test2->getName();
system("timeout 3");
return 0;
}
这是完整的构建错误:
1>------ Build started: Project: SerializableTest, Configuration: Debug Win32 ------
1>TestObject.cpp
1>Serializable.cpp
1>k:\programme\c++\serializabletest\networkdebugs\serializabletest\lib\cereal\include\cereal\cereal.hpp(462): error C2338: cereal could not find any output serialization functions for the provided type and archive combination.
1>
1> Types must either have a serialize function, load/save pair, or load_minimal/save_minimal pair (you may not mix these).
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>k:\programme\c++\serializabletest\networkdebugs\serializabletest\lib\cereal\include\cereal\cereal.hpp(347): note: see reference to function template instantiation 'ArchiveType &cereal::OutputArchive<ArchiveType,1>::processImpl<std::shared_ptr<Serializable>,0>(const T &)' being compiled
1> with
1> [
1> ArchiveType=cereal::PortableBinaryOutputArchive,
1> T=std::shared_ptr<Serializable>
1> ]
1>k:\programme\c++\serializabletest\networkdebugs\serializabletest\lib\cereal\include\cereal\cereal.hpp(347): note: see reference to function template instantiation 'ArchiveType &cereal::OutputArchive<ArchiveType,1>::processImpl<std::shared_ptr<Serializable>,0>(const T &)' being compiled
1> with
1> [
1> ArchiveType=cereal::PortableBinaryOutputArchive,
1> T=std::shared_ptr<Serializable>
1> ]
1>k:\programme\c++\serializabletest\networkdebugs\serializabletest\lib\cereal\include\cereal\cereal.hpp(290): note: see reference to function template instantiation 'void cereal::OutputArchive<cereal::PortableBinaryOutputArchive,1>::process<std::shared_ptr<Serializable>&>(T)' being compiled
1> with
1> [
1> T=std::shared_ptr<Serializable> &
1> ]
1>k:\programme\c++\serializabletest\networkdebugs\serializabletest\lib\cereal\include\cereal\cereal.hpp(290): note: see reference to function template instantiation 'void cereal::OutputArchive<cereal::PortableBinaryOutputArchive,1>::process<std::shared_ptr<Serializable>&>(T)' being compiled
1> with
1> [
1> T=std::shared_ptr<Serializable> &
1> ]
1>k:\programme\c++\serializabletest\networkdebugs\serializabletest\serializable.cpp(8): note: see reference to function template instantiation 'ArchiveType &cereal::OutputArchive<ArchiveType,1>::operator <<<std::shared_ptr<Serializable>&>(T)' being compiled
1> with
1> [
1> ArchiveType=cereal::PortableBinaryOutputArchive,
1> T=std::shared_ptr<Serializable> &
1> ]
1>k:\programme\c++\serializabletest\networkdebugs\serializabletest\serializable.cpp(8): note: see reference to function template instantiation 'ArchiveType &cereal::OutputArchive<ArchiveType,1>::operator <<<std::shared_ptr<Serializable>&>(T)' being compiled
1> with
1> [
1> ArchiveType=cereal::PortableBinaryOutputArchive,
1> T=std::shared_ptr<Serializable> &
1> ]
1>k:\programme\c++\serializabletest\networkdebugs\serializabletest\lib\cereal\include\cereal\cereal.hpp(851): error C2338: cereal could not find any input serialization functions for the provided type and archive combination.
1>
1> Types must either have a serialize function, load/save pair, or load_minimal/save_minimal pair (you may not mix these).
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>k:\programme\c++\serializabletest\networkdebugs\serializabletest\lib\cereal\include\cereal\cereal.hpp(730): note: see reference to function template instantiation 'ArchiveType &cereal::InputArchive<ArchiveType,1>::processImpl<std::shared_ptr<Serializable>,0>(const T &)' being compiled
1> with
1> [
1> ArchiveType=cereal::PortableBinaryInputArchive,
1> T=std::shared_ptr<Serializable>
1> ]
1>k:\programme\c++\serializabletest\networkdebugs\serializabletest\lib\cereal\include\cereal\cereal.hpp(730): note: see reference to function template instantiation 'ArchiveType &cereal::InputArchive<ArchiveType,1>::processImpl<std::shared_ptr<Serializable>,0>(const T &)' being compiled
1> with
1> [
1> ArchiveType=cereal::PortableBinaryInputArchive,
1> T=std::shared_ptr<Serializable>
1> ]
1>k:\programme\c++\serializabletest\networkdebugs\serializabletest\lib\cereal\include\cereal\cereal.hpp(660): note: see reference to function template instantiation 'void cereal::InputArchive<cereal::PortableBinaryInputArchive,1>::process<std::shared_ptr<Serializable>&>(T)' being compiled
1> with
1> [
1> T=std::shared_ptr<Serializable> &
1> ]
1>k:\programme\c++\serializabletest\networkdebugs\serializabletest\lib\cereal\include\cereal\cereal.hpp(660): note: see reference to function template instantiation 'void cereal::InputArchive<cereal::PortableBinaryInputArchive,1>::process<std::shared_ptr<Serializable>&>(T)' being compiled
1> with
1> [
1> T=std::shared_ptr<Serializable> &
1> ]
1>k:\programme\c++\serializabletest\networkdebugs\serializabletest\serializable.cpp(17): note: see reference to function template instantiation 'ArchiveType &cereal::InputArchive<ArchiveType,1>::operator >><std::shared_ptr<Serializable>&>(T)' being compiled
1> with
1> [
1> ArchiveType=cereal::PortableBinaryInputArchive,
1> T=std::shared_ptr<Serializable> &
1> ]
1>k:\programme\c++\serializabletest\networkdebugs\serializabletest\serializable.cpp(17): note: see reference to function template instantiation 'ArchiveType &cereal::InputArchive<ArchiveType,1>::operator >><std::shared_ptr<Serializable>&>(T)' being compiled
1> with
1> [
1> ArchiveType=cereal::PortableBinaryInputArchive,
1> T=std::shared_ptr<Serializable> &
1> ]
1>main.cpp
1>Generating Code...
1>Done building project "SerializableTest.vcxproj" -- FAILED.
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
【问题讨论】:
-
添加公共默认ctor?
-
@Yakk 添加了一个空的公共默认 ctor,但它仍然无法正常工作。
-
在哪种类型上?每个人?如果没有多态性(即使用智能指针)作为第一步,你能做到这一点吗?
-
@Yakk-AdamNevraumont 我已编辑代码以将默认构造函数添加到每个类。它在没有多态类型的情况下工作。
-
其次:在
Serializable::serialize中创建一个本地 对象ss,然后通过reference 返回该对象。你不觉得可能有问题吗? (考虑到函数结束后局部变量会被销毁......);)
标签: c++ visual-studio serialization cereal