【问题标题】:Find and erase element from STL container while iterating迭代时从 STL 容器中查找和擦除元素
【发布时间】:2017-11-06 14:48:02
【问题描述】:

在迭代 multimap 时,我想删除元素,但不仅仅是迭代器指向的元素。

for (vector<int> myVec : myVectors)
{
    auto range = myMultiMap.equal_range(myVector);
    for (auto it = range.first; it != range.second; ++it)
    {
        // secondPair is another element of this multimap
        auto secondPair = getSecondPair(it, myMultiMap);
        if (condition)
        {
            it = myMultiMap.erase(it);
            auto finder = myMultiMap.find(secondPair);
            // how can I delete secondPair?
        }
    }
}

也许这是这里的 xy 问题,所以让我解释一下我需要这个:我正在尝试做的是缩短一组 vector&lt;int&gt;。每个元素都有MyPair 类型的关联元素。这些关联的元素存储在一个无序的多图中。

typedef unordered_multimap < vector<int>, MyPair, SomeHash > MyMultiMap;

如果多重映射中的所有关联对都已成功处理,则可以删除set&lt;vector &lt;int&gt; &gt; 的元素。对于他们中的大多数人来说,这不会成功,所以他们中的大多数人预计会留在系列中。我的想法是从多图中删除元素,如果多图中不再有关联的元素,则意味着可以从集合中删除该元素。 在这里,我又遇到了在迭代时从集合中删除元素的问题。同样,不仅仅是迭代器指向的那个。

【问题讨论】:

  • 您需要就地执行此操作,还是可以复制到一个临时集并将swap 复制到myVectors?
  • 仅供参考,同时说 it = myMultiMap.erase(it) 和 ++it 可能会导致一些错误。
  • @Caleth 我可以。如果这是一个好的解决方案。

标签: c++ c++11


【解决方案1】:

来自cppreferenceunordered_multimap::erase:

对已擦除元素的引用和迭代器无效。其他迭代器和引用不会失效。

所以我认为,如果您获得了 secondPair 和 secondPairIt != it 的迭代器,那么您可以安全地擦除 secondPairIt。您还应该检查您是否没有使范围的结尾无效。

for (auto it = range.first; it != range.second;)
{
    if (condition)
    {
        auto secondPairIt = getSecondPairIt(it, myMultiMap); // Assume this is not end
        if (secondPairIt != it)
        {      
           if (secondPairIt == range.second)
               range.second = myMultiMap.erase(secondPairIt);
           else
               myMultiMap.erase(secondPairIt);
        }
        it = myMultiMap.erase(it);
    }
    else
    {
        ++it;
    }
}

【讨论】:

  • 感谢您纠正我增加迭代器的错误,即使在调用 it = myMultiMap.erase(it) 时也是如此。
猜你喜欢
  • 2013-01-28
  • 2013-04-07
  • 1970-01-01
  • 2011-03-22
  • 2010-11-05
  • 1970-01-01
  • 2014-06-11
  • 2012-03-28
  • 1970-01-01
相关资源
最近更新 更多