STL迭代器异常 map,set的erase()和insert()操作

我们都知道在STL中有迭代器,但是erase()和insert()操作会使迭代器异常

erase()会删除迭代器

例如:

set<int>st;
set<int>::iterator it = st.begin()
for(it;it!=st.end();it++)
{
    erase(*it);
}

我们通常会这样来删除set中的元素,但是这样删除的话,会把迭代器一起删除,而不仅仅删除了元素。

 

我们在删除元素的时候,要返回迭代器,因为迭代器会自动指向下一个位置

set<int>st;
set<int>::iterator it = st.begin()
for(it;it!=st.end();it++)
{
    it = it.erase(*it);
    
    //it.erase(it++);  第二种方法
}

这样就可以了,map同理

解释一下第二种方法:在删除迭代器时候执行it++

原理解析:

// postfix form: fetch and increment
map<int, int>::iterator operator++(int)//通过一个多余的int参数与prefix++区分
{
    map<int, int>::iterator tmp = *this; // fetch
    increment(); // increment,map内部由红黑树实现,此函数负责指向下一个有序元素的iterator
    return tmp; // return what was
}

首先会存储当前的位置,然后increment()把this移到了下一个位置,但是返回的tmp是旧的*this

然后参数调用优先级高于函数调用。相当于多了一个中间变量tmp。

这是++it的源码:

// prefix form: increment and fetch
map<int, int>::iterator& operator++()
{
    increment(); // increment
    return *this; // fetch
}

少了一个中间变量的赋值,所以++it比it++的效率更高一些

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章