如何从stl数据结构中擦除reverse_iterator? [英] How do I erase a reverse_iterator from an stl data structure?

查看:112
本文介绍了如何从stl数据结构中擦除reverse_iterator?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

由于某些原因,以下代码失败。你不能简单地通过使用它的base()方法擦除reverse_iterator。

For some reason the following code fails. You can't simply erase a reverse_iterator by using its base() method.

#include <set>
#include <iostream>

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

    std::set<int>::reverse_iterator rev_iter = setOfInts.rbegin();
    std::set<int>::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,你该如何擦除呢?

How does one go about correctly doing the above? Given a reverse_iterator that corresponds to something you want to erase, how do you erase it?

注意,擦除不会使用reverse_iterators。

Note, erase won't take reverse_iterators unfortunately. It wants the real thing.

推荐答案

显然,解决方案是base()返回的是1。以下身份适用于reverse_iterator:

Apparently the solution is what base() returns is 1 off. The following identity holds for a reverse_iterator:

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

或者换句话说,reverse_iterator总是一次通过它作为基础的常规迭代器。不确定原因。

Or in other words, the reverse_iterator is always one pass the regular iterator it is the base of. Not sure why.

只需更改

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

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

我非常好奇,为什么上面的身份是有意义的。

I'm definitely curious though as to why the identity above makes sense.

回到工作中,在visual studio中尝试这个,我看到上面的解决方案不行。 nextIter在擦除时变为无效。

Coming back into work and trying this in visual studio, I see the above solution doesn't quite work. The "nextIter" becomes invalid on the erase. Instead, you need to save away the temporary from the erase to get the next iterator instead of keeping around a nextIter like above.

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

最后的解决方案是

int main()
{
    using namespace std;

    set<int> setOfInts;
    setOfInts.insert(1);
    setOfInts.insert(2);
    setOfInts.insert(3);

    set<int>::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<int>::iterator tempIter = setOfInts.erase( --rev_iter.base());
    		rev_iter = set<int>::reverse_iterator(tempIter);			
    	}
    	else
    	{
    		++rev_iter;
    	}
    }	

}

关联容器不会从迭代器返回一个迭代器。所以这个解决方案不适用于map,multimap等。

Note, associative containers do not return an iterator from erase. So this solution wouldn't work for map, multimap, etc.

这篇关于如何从stl数据结构中擦除reverse_iterator?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆