STL中的容器按存储方式分为两类:一类是按以数组形式存储的容器(如:vector,deque);另一类是以不连续的节点形式存储的容器(如:list,map,set)。 在使用erase方法删除元素时,迭代器有时候会失效。在Effective STL,条款9,找到了erase容器中元素的原则。
1. 对于关联容器(如map, set, multimap,multiset),删除当前的iterator,仅仅会使当前的iterator失效,只要在erase时,递增当前iterator即可。这是因为map之类的容器,使用了红黑树来实现,插入、删除一个结点不会对其他结点造成影响。
错误的使用方法:
std::map<string, string> mapTest;
std::map<string, string>::iterator iter;
for ( iter = mapTest.begin();iter != mapTest.end(); iter ++ )
{
if ( iter->second == "test" )
{
mapTest.erase( iter );
}
}
正确的使用方法1:
std::map<string, string> mapTest;
std::map<string, string>::iterator iter;
for ( iter = mapTest.begin();iter != mapTest.end();)
{
if ( iter->second == "test" )
{
mapTest.erase( iter++ );
}
else
{
iter++; // Use Pre Increment for efficiency.
}
}
因为iter传给erase方法的是一个副本,iter++会指向下一个元素。 正确的使用方法2:
std::map<string, string> mapTest;
std::map<string, string>::iterator iter;
for ( iter = mapTest.begin();iter != mapTest.end();)
{
if ( iter->second == "test" )
{
iter = mapTest.erase( iter );
}
else
{
++iter; // Use Pre Increment for efficiency.
}
}
2. 对于序列式容器(如vector,deque),删除当前的iterator会使后面所有元素的iterator都失效。这是因为vetor,deque使用了连续分配的内存,删除一个元素导致后面所有的元素会向前移动一个位置。还好erase方法可以返回下一个有效的iterator。 3. 对于list来说,它使用了不连续分配的内存,并且它的erase方法也会返回下一个有效的iterator,因此上面两种正确的方法都可以使用。 其他链接:
http://www.cppblog.com/Herbert/archive/2009/01/08/70479.html
其他链接:
http://blog.csdn.net/kay226/article/details/6126515
其他链接:
http://www.cppblog.com/humanchao/archive/2013/04/22/199630.html
posted on 2013-10-14 18:22
王海光 阅读(982)
评论(0) 编辑 收藏 引用 所属分类:
STL