在从磁盘写入和读取的结构中使用 std::bitset 可以吗?

Is it ok to use std::bitset in a struct that is written and read from disk?

我需要在文件中存储位,std::bitset 非常适合这个,因为当我再次读取结构时需要它的许多操作。 class 似乎只包含一个位数组,没有其他成员数据。

所以不用这个

BYTE minuteOfDay[(60 * 24 / CHAR_BIT) + ((60 * 24 % CHAR_BIT) ? 1 : 0)];

我可以有这个:

std::bitset<60 * 24> minuteOfDay;

如果 class 应该随着未来的 Visual Studio 版本而改变并且我需要读取用旧版本编写的文件,我想我仍然可以复制旧的 <bitset> header进入我的项目。

但就在做出一个非常愚蠢的决定之前:这个想法是否因为某种我现在无法预见的原因而存在某种缺陷?

我知道将其写入文件是指获取 std::bitset 变量的地址并写入原始字节?在这种情况下,答案是 NO。此过程称为实体序列化或实体编码,您不能实体序列化 std::bitset(或任何包含它作为成员字段的 class),因为 std::bitset 不是 标准布局类型。

Is this idea somehow flawed ...?

是的。

首先,故障模式:如您所料,std::bitset 可能会改变其内部表示。除此之外,它无论如何都不是(保证是)标准布局类型,所以初始写入是ill-defined。除了 that,你会如何读回它?大概只是读入了一个correctly-aligned缓冲区和type-pun吧?那也是违法的。

其次,建议的修复:复制旧的 <bitset> header 太可怕了。它不会成为实际标准库的一部分,并且仍会非法将自身注入到命名空间 std 中。某些 other 代码完全有可能使用本机 std::bitset 并导致可怕的错误。

最重要的是,当脱离标准库的本机版本时,它可能根本无法工作。

三、正确解法:要么

  1. (de)序列化为某种well-defined格式,使用std::bitset

    的public接口

    请注意,无论如何这都是微不足道的:std::bitset::to_string 已经存在,您可以 re-construct 来自该字符串的实例

  2. 写一个由你控制的替换class并保证可以简单地序列化。仅仅因为您没有免费获得 std::bitset 并不意味着您必须 将岩石放在一起 使用原始字符数组。