gpt4 book ai didi

c++ - 如何将 boost::serialization 与嵌套结构和最少的代码更改一起使用?

转载 作者:行者123 更新时间:2023-12-03 18:56:28 33 4
gpt4 key购买 nike

目前我们使用存储在嵌套结构中的 POD。例子:

#define MaxNum1 100;
#define MaxNum2 50;

struct A
{
int Value[MaxNum1];
char SomeChar = 'a';
};

struct B
{
A data[MaxNum2];
float SomeFloat = 0.1f;
};


int main()
{
B StructBObject = {};
}

我们想使用 std::vector 来 boost 我们的数据结构,就像这样:
struct NewA
{
std::vector<int> Value;
char SomeChar = 'a';
};

struct NewB
{
std::vector<NewA> data;
float SomeFloat = 0.1f;
};

int main()
{
NewB StructNewBObject = {};
}

反对这种修改的唯一理由是 NewANewB不再是 POD,这使得读取/写入文件更加复杂。

怎么可能读/写 NewANewB使用 boost::serialization 到文件用最少的
代码更改为 NewANewB ?最少的代码更改很重要,因为我们使用例如具有多达 7 个嵌套级别的大结构。

最佳答案

您可以使用 boost 序列化¹进行序列化:

template <typename Ar> void serialize(Ar& ar, A& a, unsigned) {
ar & a.Value & a.SomeChar;
}
template <typename Ar> void serialize(Ar& ar, B& b, unsigned) {
ar & b.data & b.SomeFloat;
}

使用这些,您将已经拥有 C 数组和 std::vector 方法的开箱即用的正确行为。

如果你想继续使用固定大小的普通可复制类型²,你可以使用类似 Boost Container 的 static_vector :它将跟踪当前大小,但数据是在结构内部静态分配的。

三重演示

这是一个包含三个实现的三重演示程序,具体取决于 IMPL多变的。

如您所见,大部分代码保持不变。但是,为了“最佳比较”,我已确保所有容器在序列化之前都处于一半容量 (50/25)。

主程序也反序列化。

Live On Coliru
#include <boost/iostreams/device/back_inserter.hpp>
#include <boost/iostreams/device/array.hpp>
#include <boost/iostreams/stream.hpp>

#include <boost/archive/binary_oarchive.hpp>
#include <boost/archive/binary_iarchive.hpp>

#include <boost/serialization/access.hpp>
#include <boost/serialization/is_bitwise_serializable.hpp>
#include <boost/serialization/binary_object.hpp>

#include <iostream>

#if (IMPL==0) // C arrays
struct A {
int Value[100];
char SomeChar = 'a';
};

struct B {
A data[50];
float SomeFloat = 0.1f;
};

template <typename Ar> void serialize(Ar& ar, A& a, unsigned) {
ar & a.Value & a.SomeChar;
}
template <typename Ar> void serialize(Ar& ar, B& b, unsigned) {
ar & b.data & b.SomeFloat;
}

#elif (IMPL==1) // std::vector
#include <boost/serialization/vector.hpp>
struct A {
std::vector<int> Value;
char SomeChar = 'a';
};

struct B {
std::vector<A> data;
float SomeFloat = 0.1f;
};

template <typename Ar> void serialize(Ar& ar, A& a, unsigned) {
ar & a.Value & a.SomeChar;
}
template <typename Ar> void serialize(Ar& ar, B& b, unsigned) {
ar & b.data & b.SomeFloat;
}

#elif (IMPL==2) // static_vector
#include <boost/serialization/vector.hpp>
#include <boost/container/static_vector.hpp>
struct A {
boost::container::static_vector<int, 100> Value;
char SomeChar = 'a';
};

struct B {
boost::container::static_vector<A, 50> data;
float SomeFloat = 0.1f;
};

template <typename Ar> void serialize(Ar& ar, A& a, unsigned) {
ar & boost::serialization::make_array(a.Value.data(), a.Value.size()) & a.SomeChar;
}
template <typename Ar> void serialize(Ar& ar, B& b, unsigned) {
ar & boost::serialization::make_array(b.data.data(), b.data.size()) & b.SomeFloat;
}

#endif

namespace bio = boost::iostreams;
static constexpr auto flags = boost::archive::archive_flags::no_header;
using BinaryData = std::vector</*unsigned*/ char>;

int main() {
char const* impls[] = {"C style arrays", "std::vector", "static_vector"};
std::cout << "Using " << impls[IMPL] << " implementation: ";
BinaryData serialized_data;

{
B object = {};
#if IMPL>0
{
// makes sure all containers half-full
A element;
element.Value.resize(50);
object.data.assign(25, element);
}
#endif

bio::stream<bio::back_insert_device<BinaryData>> os { serialized_data };
boost::archive::binary_oarchive oa(os, flags);

oa << object;
}

std::cout << "Size: " << serialized_data.size() << "\n";

{
bio::array_source as { serialized_data.data(), serialized_data.size() };
bio::stream<bio::array_source> os { as };
boost::archive::binary_iarchive ia(os, flags);

B object;
ia >> object;
}
}

打印
Using C style arrays implementation: Size: 20472
Using std::vector implementation: Size: 5256
Using static_vector implementation: Size: 5039

最后的想法

也可以看看:
  • Boost serialization bitwise serializability
  • https://www.boost.org/doc/libs/1_72_0/libs/serialization/doc/wrappers.html#binaryobjects


  • ¹(但请记住可移植性,因为您可能已经了解 POD 方法,请参阅 C++ Boost::serialization : How do I archive an object in one program and restore it in another?)

    ² 不是 POD,与 NSMI 一样,您的类型不是 POD

    关于c++ - 如何将 boost::serialization 与嵌套结构和最少的代码更改一起使用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60303538/

    33 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com