C++ std::reverse_迭代器的缺点是什么?

C++ std::reverse_迭代器的缺点是什么?,c++,boost,stl,iterator,C++,Boost,Stl,Iterator,boost的文档声明,boost::reverse_迭代器“纠正了C++98的std::reverse_迭代器的许多缺点。” 这些缺点是什么?我似乎找不到对这些缺点的描述 后续问题: boost::reverse_iterator是如何纠正这些缺点的?好吧,最大的问题是它们不是前向迭代器,有些东西非常需要前向迭代器。所以,你必须做一些有趣的转换才能让事情顺利进行。列举一些问题 某些版本的erase()和insert()需要迭代器,而不是反向迭代器。这意味着,如果使用反向迭代器,并且希望inser

boost的文档声明,
boost::reverse_迭代器
“纠正了C++98的std::reverse_迭代器的许多缺点。”

这些缺点是什么?我似乎找不到对这些缺点的描述

后续问题:


boost::reverse_iterator是如何纠正这些缺点的?

好吧,最大的问题是它们不是前向迭代器,有些东西非常需要前向迭代器。所以,你必须做一些有趣的转换才能让事情顺利进行。列举一些问题

  • 某些版本的
    erase()
    insert()
    需要迭代器,而不是反向迭代器。这意味着,如果使用反向迭代器,并且希望
    insert()
    erase()
    ,则必须使用反向迭代器的
    base()
    函数来获得正向迭代器。没有自动转换

  • base()
    返回在插入方面与反向迭代器等效的正向迭代器。也就是说,在当前元素前面插入insert。因此,如果
    base()
    为您提供了指向同一元素的迭代器,则反向迭代器指向的元素将是错误的元素。因此,它指向一个前方,您可以使用它进行插入

  • 由于
    base()
    返回指向不同元素的迭代器,因此
    erase()
    使用的元素不正确。如果您从
    base()
    在迭代器上调用
    erase()
    ,您将从反向迭代器指向的元素中向前擦除容器中的一个元素,因此您必须在调用
    base()
    之前递增反向迭代器,以便获得用于
    erase()
    的正确正向迭代器

  • 甚至可以将
    base()
    erase()
    一起使用来正确擦除元素,这完全取决于您的实现。它适用于gcc,但对于Visual Studio,它们实际上只是以一种方式包装了一个正向迭代器,使得在处理反向迭代器和Visual Studio时使用
    erase()
    不起作用。我不记得<代码>插入()>代码>是否有相同的问题,但是反向迭代器在C++的不同实现之间不起作用(根据VisualStudio的家伙,标准不够清楚),所以除了简单地迭代容器之外,使用它们可能有点毛病。

  • 可能还有其他问题,但是处理非常量以外的任何类型的迭代器,C++中的前向迭代器在做任何事情而不是简单地迭代容器时会有点毛茸茸的,如果你甚至可以做所有的事情,因为很多函数需要非const向前迭代器,而不是任何其他类型的迭代器。 如果您真的想知道各种迭代器类型之间的差异以及与之相关的问题,我建议您阅读Scott Meyer的有效STL。它有一个关于迭代器的章节


    编辑:至于Boost的反向迭代器如何纠正这些缺点,我恐怕没有任何线索。我知道标准反向迭代器的一些缺点,过去也曾被它们所诟病,但我从来没有太多地使用过Boost,所以我对它们的反向迭代器一点也不熟悉。抱歉。

    这通常有点……不成熟。我只是猜测一下,作为评论发布:
    std::reverse_iterator
    的早期实现有时会有bug。Boost可能只是试图避开这种情况。也许评论更多的是关于
    reverse\u iterator
    实现中的缺点,而不是标准中的缺点?我不确定我是否明白您的意思。“期望”前向迭代器的代码不应该“注意”任何差异,除非它们使用未定义的行为进行操作…C++03中的std::reverse_迭代器模板公开了与基础迭代器相同的迭代器类别,它必须至少是一个双向迭代器,所以一个反向迭代器总是至少是一个bi di迭代器(因此也是一个正向迭代器)。我不相信你在这里是正确的。我相信反向迭代器实际上是正向迭代器。至少我看不出它在哪里违反了这个概念。对于
    boost::reverse_iterator
    ,您描述的问题中哪些是“已解决”的,哪些是不同的?从
    boost::reverse_iterator
    文档中可以看出,
    base()
    (和
    operator*()
    )的行为与
    std::reverse_iterator
    的行为相同。请查看我的后续问题。