C++ Cereal:序列化C风格数组

5

你如何使用cereal库来序列化数组?

例如:

void save(Archive & ar, const unsigned int version) const
{
    unsigned int l  = g1_size_bin(g,POINT_COMPRESS);
    uint8_t data[l];
    memset(data, 0, l);
    g1_write_bin(data, l, g,POINT_COMPRESS);
    ar(l);
    ar(data); // what should be here
}

那样做是不行的(我也不指望它能够成功)。同样,也不会有任何效果。

ar(cereal::binary_data(data,l)); 

我认为这应该可以工作,因为它看起来像是你会使用的boost代码,但实际上会出现编译错误:

/usr/local/include/cereal/cereal.hpp:79:17: 注意:候选函数模板被忽略:替换失败:可变长度类型“unsigned char (&)[l]”不能用作模板参数 BinaryData binary_data( T && data, size_t size )

也不行。

ar.saveBinaryValue(data,l);

因为该方法似乎仅支持XML/Json,而我需要一个二进制存档。

1个回答

11

cereal::binary_data是在假定你希望得到POD数组的二进制表示时应该使用的正确结构。这仅适用于支持binary_data(二进制和portable_binary)的归档。对于基于文本的归档,binary_data不起作用,因为它被视为更通用的序列化方法的优化 - 例如请参见向量如何序列化。

无论如何,这里是一个序列化C风格数组的工作示例:

#include <cereal/archives/binary.hpp>
#include <iostream>

int main()
{
  std::stringstream ss;

  {
    cereal::BinaryOutputArchive ar(ss);
    std::uint8_t data[] = {1, 2, 3};
    ar( cereal::binary_data( data, sizeof(std::uint8_t) * 3 ) );
  }

  {
    cereal::BinaryInputArchive ar(ss);
    std::uint8_t data[3];
    ar( cereal::binary_data( data, sizeof(std::uint8_t) * 3 ) );

    for( int i : data )
      std::cout << i << " ";
  }

  return 0;
}

如果您希望将C语言样式的数组序列化为文本存档,或者如果您的数组不是POD类型,则需要逐个迭代每个对象并单独进行序列化。


我有一个包含N个结构体的数组(在堆上),每个结构体内部包含2个双精度浮点数(x和y)。我应该为序列化遍历每个结构体吗? - Coldsteel48
如果你将ar重命名为a,这段代码看起来会更加清晰易读。 - Hi-Angel
我正在搜索与序列化和cereal相关的另一件事情,然后我遇到了这个答案。但是我有一个问题。默认情况下,ss只有std::ios_base :: in | std::ios_base :: out模式。这不会出现问题吗?它应该具有std::ios_base :: binary打开模式,不是吗? - Arda Aytekin
@ArdaAytekin 您是正确的 - 为了安全起见(不幸的是更加冗长),应该提供std::ios_base::binary以及适当的输入或输出标志。 - Azoth
谷物很棒。但是不同的存档提供不同的接口,这真是太遗憾了。现在我的代码需要知道存档类型。是否有统一的接口? - Sergei

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接