【问题标题】:Type Traits of trivially serializable C++ classes可简单序列化的 C++ 类的类型特征
【发布时间】:2016-08-15 10:17:57
【问题描述】:

我有一个定义为 A a; 的 C++ 类,我想对其进行序列化。最简单的方法(当它有效时)是

write(fd, reinterpret_cast<uint8_t*>(&a), sizeof(a));

并使用以下方法读回:

read(fd, reinterpret_cast<uint8_t*>(&a), sizeof(a));

我知道如果std::is_pod&lt;A&gt;::value 是真正的类型,这将起作用,但是A 必须表现出的最宽松的类型特征集是什么才能起作用?

为了完整起见,这是为了在应用程序的运行实例之间保持持久性,不需要其他程序或在其他平台上读取文件。

【问题讨论】:

  • 是的,你是对的。修复了 uint8_t* 错字

标签: c++ serialization


【解决方案1】:

将对象的按位图像写入流并通过从该流中读取来正确恢复它与memcpy 下正确行为的对象完全相同。为此,有 begin trivially copyable 的特定属性。所以您要使用的 trait 是 std::is_trivially_copyable&lt;A&gt;


不相关的旁注:理论上,您的代码可能具有未定义的行为。这是因为 C++ 只允许通过类型 charunsigned char 进行别名,并且不能保证 std::uint8_t 是其中之一的别名。你最好明确使用unsigned char

write(fd, reinterpret_cast<unsigned char*>(&a), sizeof(a));

【讨论】:

    【解决方案2】:

    根据 agnew 的回答,您正在寻找的是 is_trivially_copyable。但是,thjis 并不意味着 可轻松序列化,因为

    • 不同编译器/编译选项上的不同数据类型大小
    • 不同编译器/平台/编译选项的不同对齐方式
    • 不同平台上的字节顺序

    此外,您遇到版本控制问题,并且数据的含义在不同的执行机器上可能会有所不同。

    这就是为什么我建议引入自定义特征is_doron_serializabe,并将其默认为false,用于未明确标记为兼容的类型。

    (您的计划可能在某些情况下是可以的。)

    【讨论】:

    • 引用问题:“只是为了完整性,这是为了在应用程序的运行实例之间保持持久性,不需要另一个程序或另一个平台上的文件可以读取。”所以对齐、大小、字节序等都不是问题。另外,为什么你提议的特质中有我的名字?
    • 仍然提到它们,因为大多数序列化机制 开始 以这样的“它很简单,因为”放松,然后增长一个 kind-of-version-header,skip-this- if-you-dont-understand-this 块,具有更改对齐方式的磨合,并且冗余折叠在探测相等性时具有未初始化的填充字节的磨合等。它是一个接口,最好这样对待它。 ---- 你的名字在那里,因为我对你的代码一无所知,这只是一个例子。
    • 天啊!抱歉,找了你的名字,因为我想参考你的答案,把它弄混了。
    猜你喜欢
    • 2022-08-08
    • 1970-01-01
    • 2016-09-13
    • 1970-01-01
    • 1970-01-01
    • 2021-09-14
    • 2010-12-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多