1

我对谷物很陌生,我有一个(可能很简单)的问题:

当我不知道(XML)存档中的对象数量时,有没有办法反序列化多个对象?

我试过类似的东西:

std::ifstream is("c:\\data.xml");
cereal::XMLInputArchive archive(is);

while (is.good() && !is.eof())
{               
    try{
        ObjectIn oIn;
        archive(oIn);
        objectList.push_back(oIn);
    }
    catch (exception e){
    }
}

假设我在 XML 文件中有 3 个对象,而我收到的 XML 没有包含对象编号。因此,在我的代码中,前 3 次迭代是可以的,但第 4 次生成“CerealTest.exe 中 0x0035395E 处的未处理异常:0xC0000005:访问冲突读取位置 0x00000018。”

你有什么建议吗?

4

1 回答 1

4

在尝试回答您的问题之前,让我问您一个问题:如果您正在序列化未知数量的项目,为什么不将这些项目放置在一些旨在容纳可变数量项目的容器中?您可以使用 anstd::vector来存储ObjectIn并轻松处理任意数量的它们。您的代码将类似于:

std::vector<MyObjects> vec;
{
  cereal::XMLInputArchive ar("filename");
  ar( vec );
} // get in the habit of using cereal archives in an RAII fashion

以上适用于任何数量的序列化对象,假设谷物开始生成 XML。您甚至可以在 XML 代码中从向量中添加或删除元素,它会正常工作。


如果你坚持要读取一些未知数量的对象,而不是将它们放在一个旨在容纳可变数量元素的容器中,你可以这样做(但要注意这不是一个好主意——你应该真正尝试改变你的序列化策略而不是这样做):

{
  cereal::XMLInputArchive ar("filename");
  try
  {
    while( true )
    {
      ObjectIn ob;
      ar( ob );
      objectList.push_back(oIn);
    }
  catch( ... )
  { }
}

再次让我强调,这从根本上是您的序列化策略的一个问题,如果您不知道会有多少,您应该序列化一个容器而不是点菜项目。上面的代码无法处理其他任何内容的读取,它只是尝试盲目地读取内容,直到遇到异常。如果您的对象遵循某种命名模式,您可以使用名称-值-对 ( cereal::make_nvp) 按名称检索它们。

于 2014-04-05T05:19:15.473 回答