如何使用反向迭代器使用for循环调用擦除 [英] How to call erase with a reverse iterator using a for loop

查看:138
本文介绍了如何使用反向迭代器使用for循环调用擦除的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

关于此处提供的答案:如何致电使用反向迭代器擦除

Regarding the answer provided here: How to call erase with a reverse iterator

以下结果导致分段错误( ++ it )当编译时在g ++ 4.8.4中用-std = c ++ 11。我是否误解了答案?

The following results in a segmentation fault (upon ++it) when compiled in g++ 4.8.4 with -std=c++11. Am I misunderstanding the answer?

  std::map<int,int> testmap;
  testmap[0] = 1;
  for(auto it=testmap.rbegin(); it!=testmap.rend(); ++it) {
    testmap.erase( std::next(it).base() );
  }


推荐答案

,我认为Jarod42的回答中的循环的修改是为了使事情更安全,并保持典型的 for(;;)循环的细节:

After some use of this idiom, I think a modification to the loop in Jarod42's answer is in order to make things safer and maintain the typical for(;;) loop niceties:

for (auto it = testcont.rbegin(), nit = it; it != testcont.rend(); it = nit) {
    nit = next(it);

    // whatever... maybe a continue somewhere or maybe not

    if (WE_WANT_TO_ERASE(it)) {
        nit = decltype(it){ testcont.erase(std::next(it).base()) };
    }

    // whatever... maybe a continue somewhere or maybe not
}

在另一个答案中使用循环太危险了。如果在循环中的某处不小心地添加 continue; ,而不首先递增迭代器,结果将是一个无限循环。因为,一开始,这看起来像一个正常的 for(;;)循环,我相信这一定会发生迟早。类似地,如果在循环中有分支,并且如果那些分支中的一个忽略增加迭代器,则引入另一个错误。最后,如果你做 erase(),你需要确定 continue

Using the loop in the other answer is too dangerous. If one were to thoughtlessly add a continue; somewhere in the loop, without incrementing the iterator first, the result would be an infinite loop. Since, at first glace, this can look like a normal for(;;) loop, I believe that this is bound to happen sooner or later. Similarly, if there are branches in the loop, and if one of those branches neglects to increment the iterator, another bug is introduced. Finally, if you do an erase(), you need to be sure to continue before you increment the iterator or else you have yet another bug.

使用上面修改的循环,循环可以像普通的一样处理(;;)循环。诀窍是增加 nit (下一个迭代器)作为循环体的第一行。那么你不必担心。只有当您需要更新 nit 时,才需要更新 erase()。一切都正常工作,因为一个人期望一个for循环工作。

Using the modified loop above, the loop can be treated just like a normal for(;;) loop. The trick is to increment nit (the "next iterator") as the first line of the loop body. Then you don't have to worry. The only time you need to update nit is if you are doing an erase(). Everything else works as one would expect a for loop to work.

最后一点:我最初问地图问题,但这将正确工作向量列表等。

One final note: I originally asked the question with regard to maps, but this will work correctly for vector, list, etc, as well.

这篇关于如何使用反向迭代器使用for循环调用擦除的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆