面对现实,超越自己
逆水行舟,不进则退
posts - 269,comments - 32,trackbacks - 0
      STL中的容器按存储方式分为两类:一类是按以数组形式存储的容器(如:vector,deque);另一类是以不连续的节点形式存储的容器(如:list,map,set)。
      在使用erase方法删除元素时,迭代器有时候会失效。在Effective STL,条款9,找到了erase容器中元素的原则。

         1. 对于关联容器(如map, set, multimap,multiset),删除当前的iterator,仅仅会使当前的iterator失效,只要在erase时,递增当前iterator即可。这是因为map之类的容器,使用了红黑树来实现,插入、删除一个结点不会对其他结点造成影响。
错误的使用方法

    std::map<stringstring> mapTest;
    std::map<stringstring>::iterator iter; 
    
for ( iter = mapTest.begin();iter != mapTest.end(); iter ++ ) 
    { 
        
if ( iter->second == "test" ) 
        { 
            mapTest.erase( iter ); 
        } 
    } 

正确的使用方法1:
    std::map<stringstring> mapTest;
    std::map<stringstring>::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<stringstring> mapTest;
    std::map<stringstring>::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

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理