故障化谷物便携式结构
Trouble deserializing cereal PortableBinaryArchive
我面对一个std ::长度例外,使用谷物库将std :: vector逐个序列化。我认为如果我提供一些代码,这是最简单的。这是我的班级:
#include "cereal/archives/portable_binary.hpp"
#include "cereal/archives/json.hpp"
#include "cereal/types/vector.hpp"
enum class myType {
None, unset, Type1, Type2, Type3
};
class myClass
{
public:
myClass();
myClass(size_t siz);
~myClass();
std::vector<size_t> idxs;
myType dtype;
bool isvalid;
// This method lets cereal know which data members to serialize
template<class Archive>
void serialize(Archive & archive)
{
archive(CEREAL_NVP(dtype), CEREAL_NVP(isvalid), CEREAL_NVP(idxs));
}
protected:
private:
};
IDXS成员不一定总是相同的大小。经过一些计算后,我获得了
std::vector<myClass> allData;
我想在另一个应用程序中进行序列化和后来的序列化。这是我的序列化代码:
std::ofstream ofile(allDataFilename.c_str());
if (ofile.good())
{
cereal::PortableBinaryOutputArchive theArchive(ofile);
theArchive(allData);
//ofilefp.close(); // Do not close because of RAII where dtor of cereal archive does some work on file!
}
else
{
std::cout << "Serialization to portable binary archive failed. File not good." << "n";
}
生成的数据文件不是零大小,也不是全部零,因此从外观上可以很好。这就是我在另一个应用程序中进行的验证:
std::string allDataFilename("C:\path\to\file\data.dat");
std::ifstream infile(allDataFilename.c_str());
std::vector<myClass> myDataFromDisk;
if (infile.good())
{
cereal::PortableBinaryInputArchive inArchive(infile);
inArchive >> myDataFromDisk;
}
else
{
std::cout << "Data file unavailable." << "n";
}
当我运行此避难代码时,我会得到一个例外" std :: length_error"。以某种方式与此错误相关的讨论在这里,但对我来说,这似乎与我的案件无关。(还是?)
我尝试通过单独的负载/保存功能进行序列化,因为我不确定谷物文档的这一部分是否适用:
在可能的情况下,首选使用单个内部序列化 方法,尽管在必要时可以使用拆分方法(例如 加载类时动态分配内存)。
我还试图将IDXS成员的每个向量元素分别以循环为基础的范围(就像它在内部谷物中一样),但这两种事情无济于事。
这两种应用程序均与Visual Studio 2015更新3编辑3.我使用当前的谷物v1.2.2,但也使用谷物v1.1.2尝试了,这给了我一个相同的序列化结果。
顺便说一句:它可以与谷物json档案馆一起使用。但是只有在我将序列化调用更改为
之后archive(CEREAL_NVP(dtype), CEREAL_NVP(isvalid), CEREAL_NVP(idxs));
虽然当矢量成员首先是序列化时,它与JSON无法使用。但这可能完全无关。
archive(CEREAL_NVP(idxs), CEREAL_NVP(dtype), CEREAL_NVP(isvalid));
现在我的问题:
1)这是序列化应与谷物配合使用的方式吗?
2)我需要添加更多序列化功能吗?例如。到枚举课程?
最好的问候AverageCoder
关于序列化代码的课程没有错。您无需为枚举提供序列化,可以通过cereal/types/common.hpp
自动包含它。您的字段被序列化的顺序无关紧要。
您的错误是在执行加载和保存时未正确使用档案。谷物处理与流的所有接口,因此您不应直接在谷物档案馆直接使用流媒体操作员(即<<
或>>
)。再查看谷物网站上的示例,您会注意到,每当与谷物档案馆进行互动时,它都是通过()
操作员完成的。
在处理二进制数据的流时,您还应确保使用适当的标志(std::ios::binary
) - 这可以防止一些难以调试的问题。
这是一个使用您的班级的工作示例
#include <cereal/archives/portable_binary.hpp>
#include <cereal/archives/json.hpp>
#include <cereal/types/vector.hpp>
#include <algorithm>
#include <sstream>
enum class myType {
None, unset, Type1, Type2, Type3
};
class myClass
{
public:
myClass() = default;
myClass( myType mt, size_t i ) : isvalid( true ), dtype( mt ),
idxs( i )
{
std::iota( idxs.begin(), idxs.end(), i );
}
std::vector<size_t> idxs;
myType dtype;
bool isvalid;
// This method lets cereal know which data members to serialize
template<class Archive>
void serialize(Archive & archive)
{
archive(CEREAL_NVP(dtype), CEREAL_NVP(isvalid), CEREAL_NVP(idxs));
}
};
int main(int argc, char* argv[])
{
std::vector<myClass> allData = {{myType::None, 3}, {myType::unset, 2}, {myType::Type3, 5}};
// When dealing with binary archives, always use the std::ios::binary flag
// I'm using a stringstream here just to avoid writing to file
std::stringstream ssb( std::ios::in | std::ios::out | std::ios::binary );
{
cereal::PortableBinaryOutputArchive arb(ssb);
// The JSON archive is only used to print out the data for display
cereal::JSONOutputArchive ar(std::cout);
arb( allData );
ar( allData );
}
{
cereal::PortableBinaryInputArchive arb(ssb);
cereal::JSONOutputArchive ar(std::cout);
std::vector<myClass> data;
arb( data );
// Write the data out again and visually inspect
ar( data );
}
return 0;
}
及其输出:
{
"value0": [
{
"dtype": 0,
"isvalid": true,
"idxs": [
3,
4,
5
]
},
{
"dtype": 1,
"isvalid": true,
"idxs": [
2,
3
]
},
{
"dtype": 4,
"isvalid": true,
"idxs": [
5,
6,
7,
8,
9
]
}
]
}{
"value0": [
{
"dtype": 0,
"isvalid": true,
"idxs": [
3,
4,
5
]
},
{
"dtype": 1,
"isvalid": true,
"idxs": [
2,
3
]
},
{
"dtype": 4,
"isvalid": true,
"idxs": [
5,
6,
7,
8,
9
]
}
]
}
- 如何循环打印顶点结构
- 通过方法访问结构
- 使用不带参数的函数访问结构元素
- 预处理器:插入结构名称中的前一个行号
- 为什么在没有显式默认构造函数的情况下,将另一个结构封装在联合中作为成员的结构不能编译
- 孤立代码块在结构中引发异常
- 有什么方法可以遍历结构吗
- 如何在 C# 中映射双 C 结构指针?
- 如何在C++中使用结构生成映射
- 无法将结构注册为增强几何体3D点
- 多成员Constexpr结构初始化
- C++将文本文件中的数据读取到结构数组中
- 如何重构类层次结构以避免菱形问题
- 如何在C++中序列化结构数据
- std::vector的包装器,使数组的结构看起来像结构的数组
- 没有为自己的结构调用列表推回方法
- 奇怪的结构&GCC&clang(void*返回类型)
- 在 c++ 中拥有一组结构的正确方法是什么?
- 带有柔性阵列构件的包装结构的便携式替代方案
- 故障化谷物便携式结构