当前位置:  开发笔记 > 编程语言 > 正文

如何从stl数据结构中删除reverse_iterator?

如何解决《如何从stl数据结构中删除reverse_iterator?》经验,为你挑选了1个好方法。

由于某种原因,以下代码失败.您不能简单地使用其base()方法擦除reverse_iterator.

#include 
#include 

int main()
{
    std::set setOfInts;
    setOfInts.insert(1);
    setOfInts.insert(2);
    setOfInts.insert(3);

    std::set::reverse_iterator rev_iter = setOfInts.rbegin();
    std::set::reverse_iterator nextRevIter = setOfInts.rbegin();
    ++nextIter;

    while ( rev_iter != setOfInts.rend())
    {
        // Find 3 and try to erase
        if (*rev_iter == 3)
        {
            // SEGFAULT HERE
            setOfInts.erase( rev_iter.base());
        }
        rev_iter = nextRevIter;
        ++nextRevIter;
    }

}

如何正确地做上述事情?如果reverse_iterator对应于您想要擦除的内容,那么如何删除它?

注意,遗憾的是不会使用reverse_iterator.它想要真实的东西.



1> Doug T...:

显然,解决方案是base()返回1关闭.对于reverse_iterator,以下标识成立:

&*(reverse_iterator(i)) == &*(i - 1) 

或者换句话说,reverse_iterator始终是一个通过它的基础的常规迭代器.不知道为什么.

在GCC

简单地改变

        // SEGFAULT HERE
        setOfInts.erase( rev_iter.base());

        // WORKS!
        setOfInts.erase( --rev_iter.base());

我很清楚,为什么上面的身份才有意义.

在Visual Studio中

回到工作中并在visual studio中尝试这个,我看到上面的解决方案并不是很有效.擦除时"nextIter"变为无效.相反,你需要将擦除中的临时值保存到下一个迭代器而不是保持像上面那样的nextIter.

  set::iterator tempIter = setOfInts.erase(--rev_iter.base());
  rev_iter = setOfInts.erase(tempIter);

所以最终的解决方案是

int main()
{
    using namespace std;

    set setOfInts;
    setOfInts.insert(1);
    setOfInts.insert(2);
    setOfInts.insert(3);

    set::reverse_iterator rev_iter = setOfInts.rbegin();

    while ( rev_iter != setOfInts.rend())
    {
        // Find 3 and try to erase
        if (*rev_iter == 3)
        {
            cout << "Erasing : " << *rev_iter;
            set::iterator tempIter = setOfInts.erase( --rev_iter.base());
            rev_iter = set::reverse_iterator(tempIter);            
        }
        else
        {
            ++rev_iter;
        }
    }   

}

注意,关联容器不会从erase返回迭代器.因此,此解决方案不适用于地图,多图等.


上述标识是为了确保反向迭代器可以在所有标准位置工作,这些位置期望迭代器范围指定半开区间[first,last).如果不是这种情况,反向迭代器在std algos中将是无用的,因为'end'将被解除引用并且将跳过'begin'.
这总结了我生命中的最后几个小时:)
我认为这是因为你可以指出一个超过数组结尾但不是一个数组开始之前的数组.所以如果.rend()== i,那么i.base()== .begin(),而不是.begin() - 1(也就是UB).所以它总是一个关闭,但是当解除引用时,它返回* - .base()
推荐阅读
mobiledu2402852413
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有