为啥 std::bitset 不带有迭代器?

Posted

技术标签:

【中文标题】为啥 std::bitset 不带有迭代器?【英文标题】:Why doesn't std::bitset come with iterators?为什么 std::bitset 不带有迭代器? 【发布时间】:2016-04-16 03:25:52 【问题描述】:

std::bitset 似乎没有附带 STL 迭代器。 因此,我不能执行以下操作:

std::bitset<8> bs;
for (auto it: bs) 
    std::cout << "this can not be done out of the box\n";

相反,我必须:

std::bitset<8> bs;
for (std::size_t i = 0; i < bs.size(); ++i) 
    std::cout << bs[i] << '\n';

没有迭代器,我也无法将位集与任何 STL 算法一起使用。 为什么委员会决定从 bitset 中排除迭代器?

【问题讨论】:

作为参考,来自 B.Stroustrup:“由于历史原因,bitset 在风格上与其他标准库类不同。...没有提供迭代器。”你可以在 B .Stroustrup 的“The C++ Programming Language”一书。 "34.2.2 位集" @StahlRat 你有那个链接吗? @NathanOliver books.google.co.uk/… 【参考方案1】:

我认为从未有过将迭代器从位集中排除的实际决定。

相反,bitset 是在提议将原始标准模板库添加到 C++ 标准之前的类之一。在设计时,基本上没有标准库包含迭代器。

然后,有人提议添加 Stepanov 的库,其中相当一部分被接受了。对此,添加了一些现有的类(例如,std::string),以允许它们像新的容器类一样使用。

这一切都发生在标准流程的后期——事实上,他们已经在一些地方改变了规则以添加他们所做的事情。除其他事项外,几乎在将容器/迭代器/算法添加到库中的同时,委员会投票考虑标准“功能完整”,因此从那时起他们只致力于修复错误等,不添加新功能。

因此,即使已经编写了向bitset 添加迭代器接口的提案,委员会可能接受它的唯一方法是将其视为已修复的错误而不是新功能添加。如果有一个非常可靠的提议,我想他们可以这样做,但我不认为有这样的提议,而且它会有点牵强,所以即使是一个非常好的提案也可能很容易被拒绝。

从那时起,有一个提案LEWG 1112,它将向std::bitset 添加一个迭代器接口。这是为 C++11 提出的,专门为支持 C++11 中添加的基于范围的for 循环而提出的。它遭受了相当可耻的命运:它最初被接受,并起草了措辞。然后看起来将概念添加到语言中的提议会被接受,所以这个措辞被重写以使用闪亮的、美妙的新概念。一段时间后,概念被从语言中删除,他们没有重新措辞使其不再依赖于概念,而是暂时将其标记为“NAD Future”,这意味着他们将其视为不是缺陷,并推迟了任何进一步的工作直到将来某个(不确定的)时间(据我所知,从那以后就没有重新访问过)。

【讨论】:

同样重要的是要注意,在委员会允许代理迭代器成为真正的迭代器之前,它们不能成为正确的迭代器。大多数算法都可以假设从*it 返回的内容是对真实iterator::value_type 的真实引用,而不是可能是代理对象。 @NicolBolas:就其本身而言,当时显然并没有过多地打扰委员会(c.f. std::vector&lt;bool&gt;)。 很可能他们当时根本没有意识到这个问题。特别是在没有明确概念的情况下,低估行为是多么容易。当然,这并不是说花了很长时间才发现; the first widely publicized discussion of the problem being in 1999;在标准化之后不久,但在 STL 被半广泛使用之后。 @NicolBolas:最接近的似乎是在LEWG issue 1112,他们最初建议添加迭代器以支持基于范围的for循环,然后将其更改为使用基于概念的措辞,然后在删除概念后更改为“NAD Future”。 @RexYuan:至少在我看来,它仍然不支持迭代器。【参考方案2】:

您可以创建自己的迭代器,或者只使用mine

用法如下:

#include <bitset>
#include "bitset_iterator.h"

std::bitset<32> indices 0b10101010101010101010101010101010 ;

for (const auto& index : indices) 
  std::cout << index << ", ";

// Prints "1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, "

【讨论】:

迭代器不是这样工作的。他们需要返回对容器中元素的引用。

以上是关于为啥 std::bitset 不带有迭代器?的主要内容,如果未能解决你的问题,请参考以下文章

迭代std :: bitset中真实位的有效方法?

C++:为啥输出迭代器不支持比较操作?

向量迭代器不兼容...但是为啥呢?

为啥 C++ 字符串迭代器不检查错误?

为啥 std::set::find 不提供提示迭代器?

为啥 string_view 构造函数不采用一对迭代器