最近使用了顺序容器的删除元素操作,特此记录下该函数的注意事项。
在C++primer中对c.erase(p) 这样解释的:
c.erase(p) 删除迭代器p所指向的元素,返回一个指向被删元素之后元素的迭代器,若p指向尾元素,则返回尾后迭代器,若p是尾后迭代器,则会产生未定义行为。
这个函数我在使用的过程中发现有那么一点小小的注意事项
如果要想遍历一个容器,并且删除某个不符合要求的元素,那么最好使用while而不是使用for
因为
vector<RotatedRect>::iterator it = m_rect.begin(); while((it) != m_rect.end()){ float diff = abs((*it).size.width - (*(it + 1)).size.width); if( diff > diffmax){ if(( it - m_rect.begin()) < (m_rect.size() / 2)) it = m_rect.erase(it); //此时指针已经指向下一个元素,故指针不需要再自增 else it = m_rect.erase(it + 1); }else{ it++; //否则指针自增一,while循环可以选择有条件的让指针指向下一个元素 } }
vector<RotatedRect>::iterator it = m_rect.begin(); for( ;(it) != m_rect.end(); it++ ) //如果使用for循环,并且选择在此处自增一
{ float diff = abs((*it).size.width - (*(it + 1)).size.width); if( diff > diffmax){ if(( it - m_rect.begin()) < (m_rect.size() / 2)) it = m_rect.erase(it); //那么将会与这里的自增重复,这样会造成有元素被跳过 else it = m_rect.erase(it + 1); } }
我在查阅资料时发现有个博主推荐的写法是这样的
此处链接http://blog.csdn.net/zhuimengzh/article/details/6841500
void fun() { vector<int> iVec; vector<int>::iterator it; for(int i=0;i<10;i++) iVec.push_back(i); display(iVec); for(it=iVec.begin();it!=iVec.end();++it) { if(*it ==4 || *it == 7) { it=iVec.erase(it); --it;//这里回退一个 //******该博主推荐在此处自动回退一个,这样貌似可以用for循环了,但是其实不是的 } } display(iVec); }
如果你删除的元素是容器的第一个元素,那么回退的行为将是未定义的,切记