首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C++ >

钻个器皿erase的牛角尖(欢迎指导)

2013-02-24 
钻个容器erase的牛角尖(欢迎指导)今日工作遇到一个问题,以前一直使用以下方法中的第一种方式,连续删除关联

钻个容器erase的牛角尖(欢迎指导)
   今日工作遇到一个问题,以前一直使用以下方法中的第一种方式,连续删除关联容器元素,今日突然得见第二种方式,被告知第一种在erase的后迭代器有可能失效,此时迭代器再自加则会崩溃,貌似有些道理,所以小弟在此请教下,求解迷津。


//第一种
AssocContainer<int> c;
...
for (AssocContainer<int>::iterator i = c.begin(); i != c.end();) 
{
    if (badValue(*i)) 
      c.erase(i++);  // 对于坏的值,把当前的
     else 
      ++i;           // i传给erase,然后
}                    // 作为副作用增加i;对于好的值,只增加i

//第二种
AssocContainer<int> c;
...
for (AssocContainer<int>::iterator i = c.begin(); i != c.end();) 
{
    AssocContainer<int>::iterator  iTemp = i++; 
    if (badValue(*i)) 
      c.erase(i); // 对于坏的值,把当前的

STL?迭代器?erase
[解决办法]
iter = c.earse(..);

可以通过earse的返回值保存下个有效的iter.

或者用erase(remove....) 惯用方法.
[解决办法]
 先不说第一种和第二种erase的对象根本就不一样
你这2种方法根本就没有本质上的差别吧,erase完成后的i都是erase前的i自增后的结果

这段代码应该是effective stl上的,AssocContainer是指某一种关联容器,关联容器是有保证删除某个元素后迭代器不失效的

而对于序列容器,应该用1楼的方法,而不是lz的方法2,而这也是在effective stl里有写的
[解决办法]
iterator i   定义i为迭代器,看着真别扭
[解决办法]
第一个是正确的.
[解决办法]
引用:
第二种写错了。。粗心了
C/C++ code?1234567891011121314151617181920212223242526//第一种 AssocContainer<int> c; ... for (AssocContainer<int>::iterator iter = c.begin(); iter != c.end();)  {         if (b……



第一种, I 会先自增然后再进入erase函数. 没有问题.

[解决办法]
vector<int> vec;
for(vector<int>::iterator iter = vec.begin(); iter != vec.end();)
{
if(bad) iter = vec.erase(iter);
else ++iter;
}
[解决办法]
Quote: 引用:

        c.erase(iter++);       // 我同事的意思是,这里i是先被erase的,
                               //关联容器这个i是不是在erase之
                               //后被释放呢?然后才执行的自增,如果i已经失效,
                               //则有可能导致崩溃,如果
                               //不崩溃,则是没失效,具体估计就得开代码实现了   

Quote:

不知道是你写错了还是你和你同事根本没理解后置++的含义
iter++是对iter自增然后返回一个自增前的值,是先自增然后再erase的
erase后指向被删除的结点的迭代器自然是失效的,但是其他迭代器都是有效的
[解决办法]
对学习编程者的忠告:
眼过千遍不如手过一遍!
书看千行不如手敲一行!
手敲千行不如单步一行!
单步源代码千行不如单步对应汇编一行!

[解决办法]
两种方法都没有问题啊。

但是个人习惯用8楼的方法

引用:
vector<int> vec;
for(vector<int>::iterator iter = vec.begin(); iter != vec.end();)
{
if(bad) iter = vec.erase(iter);
else ++iter;
}

[解决办法]
Should use std::remove_if algorithm easily instead of looping through the entire container. As Associated container is sorted already, isn't it faster by using std::remove_if? Also it has less chance to have invalid iterator because you don't use it explicitly.

AssocContainer<int> c;
std::remove_if(c.begin(), c.end(), [](int i){ return badValue(i); });

[解决办法]
两种写法本质是一样的。用在list类型的没有问题,vector类型的就不行了。
一般用remove_if比较好

AssocContainer<int>::iterator remove_end = remove_if(c.begin(), c.end(), [](int elm){return badValue(elm);});
c.erase(remove_end, c.end());

[解决办法]
引用:
两种写法本质是一样的。用在list类型的没有问题,vector类型的就不行了。
一般用remove_if比较好
C/C++ code?12AssocContainer<int>::iterator remove_end = remove_if(c.begin(), c.end(), [](int elm){return badValue(elm);});c.erase……


He is talking about associative container, you don't need to use remove erase idiom.
[解决办法]
不太清楚关联容器以及erase的内部实现,第二种较第一种更靠谱一点。
[解决办法]
标准的STL关联式容器包括:set、multiset、map、multimap。
vector list什么的不是啊童鞋们。
另外删除关联容器元素的时候其他元素的迭代器不会受影响,这两种方法都可以的。

[解决办法]
引用:
标准的STL关联式容器包括:set、multiset、map、multimap。
vector list什么的不是啊童鞋们。
另外删除关联容器元素的时候其他元素的迭代器不会受影响,这两种方法都可以的。

最后一句话错了,应该使用std::remove_if. 如果你的map/set 有1百万单元, 你全部循环一遍??
[解决办法]
楼主,别钻了,买本effective stl认真啃啃
你现在问的,和即将问的,上面都有现成答案了。

热点排行