【问题标题】:Post increment on set iterator [duplicate]在集合迭代器上发布增量[重复]
【发布时间】:2013-01-04 18:10:25
【问题描述】:

可能重复:
iterator validity ,after erase() call in std::set

当我迭代一个集合并想要删除某些项目时,迭代器会改变。这会导致段错误,因为删除后迭代失败。我该如何克服这个问题?

std::set< std::pair<double,unsigned>, comparisonFunction> candidates;'
[...]

for( auto it = candidates.begin(); it != candidates.end(); ++it)
{
  [...]
  if ( some constraint satisfied)
  {
    candidates.erase(it);
  }
}

我在使用此代码时遇到了段错误。我的猜测是,这要么是由于迭代器损坏,要么是由于在某些情况下要删除的元素是最后一个元素。迭代器上的后增量是否克服了这个问题?像这样:

candidate.erase(it++);

【问题讨论】:

  • 使用erase的返回值作为迭代器恢复值,else正常递增。
  • candidates.erase( remove_if( candidates.begin(), candidates.end() ), [](){ some constraint satisfied } ), candidates.end() );
  • @Omnifarious 那是真的 - 无论如何,裁判可能会帮助 OP。
  • @K-ballo:因为 C++11 std::set::iterator 是一个 constant 双向迭代器。我几乎不相信 remove_if 可以对此进行操作。此外,如果这是可能的,您将破坏 log N 的复杂性 find()

标签: c++ iterator set


【解决方案1】:

使用erase的返回值:

it = candidates.erase(it);

请注意,如果您删除一个元素,则不能增加 it,否则您的迭代器可能会失效。

for( auto it = candidates.begin(); it != candidates.end();)
{
  if ( some constraint satisfied)
  {
    it = candidates.erase(it);
  }
  else
    ++it;
}

还要注意,这在 C++03 中是不可能的,因为 erase 没有返回任何迭代器。但是,由于您使用的是 C++11,所以应该没有问题。

参考文献

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-03-31
    • 1970-01-01
    • 2011-10-08
    • 2012-07-03
    • 1970-01-01
    • 2014-12-27
    • 2023-03-03
    相关资源
    最近更新 更多