为啥 std::vector<bool> 没有 .data()?

Posted

技术标签:

【中文标题】为啥 std::vector<bool> 没有 .data()?【英文标题】:Why does std::vector<bool> have no .data()?为什么 std::vector<bool> 没有 .data()? 【发布时间】:2018-02-17 07:58:40 【问题描述】:

std::vector&lt;bool&gt; 的特化,在 C++11 23.3.7/1 中指定,不声明 data() 成员(例如提到 here 和 here)。

问题是:为什么std::vector&lt;bool&gt; 没有.data()?这与为什么bools 的向量没有连续存储在内存中是同一个问题。不这样做有什么好处?

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

【问题讨论】:

vector&lt;bool&gt; 允许通过将多个布尔值打包在一个字节中来进行空间优化。 data() 将取消该好处。 好处是您使用的内存减少了 8 倍。缺点是你会破坏人们的期望。或多或少的结论是弊大于利。 std::vector&lt;bool&gt; 有点像邀请你的婆婆和你住在一起。这在当时似乎是个好主意,但你最终会后悔整个想法。幸运的是,我只能将这些违规行为之一归功于自己。 @Bathsheba 您设计并实现了 std::vector ?你应该感到羞耻,我要向你岳母举报你。 【参考方案1】:

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

因为std::vector&lt;bool&gt; 在 1 个字节中存储了多个值。

把它想象成一个压缩存储系统,其中每个布尔值都需要 1 位。因此,不是每个内存块有一个元素(每个数组单元一个元素),内存布局可能如下所示:

假设你想索引一个块来获取一个值,你将如何使用运算符[]?它不能返回bool&amp;(因为它将返回一个字节,其中存储了多个bools),因此您不能为其分配bool*。换句话说,bool *bool_ptr =&amp;v[0];不是有效的代码,会导致编译错误。

此外,正确的实现可能没有那种专业化并且不进行内存优化(压缩)。所以data() 必须根据实现复制到预期的返回类型(或者标准应该强制优化而不是仅仅允许它)。

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

因为std::vector&lt;bool&gt;存储为布尔数组,因此不能以直接的方式返回指针。它可以通过将数据复制到一个数组并返回该数组来做到这一点,但不这样做是一种设计选择(如果他们这样做了,我认为这对所有容器都是data(),这会产生误导) .

不这样做有什么好处?

内存优化。

通常会减少 8 倍的内存使用量,因为它将多个位存储在一个字节中。准确地说,是CHAR_BIT 的倍数。

【讨论】:

顺便说一句,正确的实现可能没有那种专业化并且不进行内存优化。所以data() 必须根据实现复制到预期的返回类型。 (或者标准应该强制优化而不是仅仅允许它)。 我没关系。顺便说一句,"布局看起来像这样:" -> 可能看起来像。因为它是特定于实现的(特别是“endianess”) @Bathsheba:我认为标准不能保证最大包装。无论 CHAR_BIT 是什么,它都允许每字节打包 8 位。

以上是关于为啥 std::vector<bool> 没有 .data()?的主要内容,如果未能解决你的问题,请参考以下文章

通过 mpi 发送一个 c++ std::vector<bool>

从 std::vector<bool> 获取字节

C++ - 将 char 引用转换为 bool 引用(std::vector<bool>)

std::vector<bool>中的坑

bcc32:专注于`std::vector<bool>`时出现奇怪的错误

在 C++ 中使用 std::vector<bool> 对象是不是可以接受,还是应该使用替代方法?