为什么std::vector<bool>没有.data()函数?

21

根据C++11 23.3.7/1的规定,std::vector<bool>的专业化没有声明data()成员(例如在这里这里提到)。

问题是:为什么std::vector<bool>没有.data()?这与为什么bool向量不在内存中连续存储完全相同。这样做的好处是什么?

为什么不能返回指向bool数组的指针?


2
vector<bool> 允许通过将多个 bool 打包在一个字节中来进行空间优化。 data() 将消除这种优势。 - Jarod42
3
好处是你使用的内存少了8倍。缺点是你会打乱人们的期望。总的来说,已经得出结论,缺点大于好处。 - nwp
5
std::vector<bool>有点像邀请岳母来和你同住。看起来可能是个好主意,但最终你会后悔这整个想法。幸运的是我只能责备自己犯了其中一个错误。 - Bathsheba
7
@Bathsheba,你设计并实现了std::vector<bool>吗?你应该感到羞耻,并且我会向你的岳母举报。 - Martin James
1个回答

34

为什么std::vector没有.data()方法?

因为std::vector<bool>在1个字节中存储多个值。

可以将其视为一种压缩存储系统,其中每个布尔值需要1位。因此,内存布局可能看起来像这样:

enter image description here

假设您想要索引一个块以获取一个值,您将如何使用运算符[]?它不能返回bool&(因为它将返回一个字节,该字节存储多个bools),因此您无法将bool*分配给它。换句话说,bool *bool_ptr =&v[0];不是有效的代码,并将导致编译错误。
此外,正确的实现可能没有那个特化并且不执行内存优化(压缩)。因此,data()必须根据实现复制到预期的返回类型(或者标准应该强制执行优化而不仅仅允许它)。
为什么不能返回指向一个bool数组的指针?
因为std::vector<bool>并不是作为bool数组存储的,因此不能直接返回指针。它可以通过将数据复制到一个数组并返回该数组来实现,但这是一种设计选择,他们没有这样做(如果他们这样做了,我认为这适用于所有容器的data(),这将是误导性的)。
不这样做的好处是什么?
内存优化。
通常节省8倍的内存使用量,因为它将多个位存储在单个字节中。确切地说,是CHAR_BIT倍。

1
顺便说一句,正确的实现可能没有那个特化并且不进行内存优化。因此,data()将根据实现需要复制到预期的返回类型。(或者标准应该强制进行优化而不仅仅是允许它)。 - Jarod42
我可以接受这个。顺便说一下,“布局看起来像这样:”可能会看起来如此,因为它是实现特定的(特别是“字节序”)。 - Jarod42
@Bathsheba:我认为标准并不保证最大的打包。它允许每个字节打包8位,而不考虑CHAR_BIT。 - MSalters
在我的看法中,如果你使用模板向量,那么摆脱抽象中的bool并将true|false类型转换为其他类型是最合乎逻辑的做法。否则,代码质量会变得更糟。布尔值就是它了。 - Kalen

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