擦除for(-each)自动循环中的项目

时间:2014-10-23 09:11:32

标签: c++ iterator std auto

有没有办法在像这样的for循环中使用自动变量时擦除特定元素?

for(auto a: m_Connections)
{
    if(something)
    {
        //Erase this element

    }
}

我知道我可以说

for(auto it=m_map.begin() ...

for(map<int,int>::iterator it=m_map.begin() ...

并手动递增迭代器(并擦除),但如果我能用更少的代码行完成,我就会更开心。

谢谢!

4 个答案:

答案 0 :(得分:6)

你做不到。基于范围的循环使得范围内的简单迭代更简单,但不支持使范围或其使用的迭代器无效的任何内容。当然,即使支持它,也无法在不访问迭代器的情况下有效地擦除元素。

你需要一个老派的循环,按照

的方式
for (auto it = container.begin(); it != container.end();) {
    if (something) {
        it = container.erase(it);
    } else {
        ++it;
    }
}

container.erase()std::remove_if的组合,如果你喜欢那种东西。

答案 1 :(得分:5)

不,没有。基于范围的循环用于访问容器的每个元素一次。

每次从容器中删除元素时,擦除元素处或之后的迭代器都不再有效(并且给定the implementation of the range-based-for这是一个问题)。

如果您需要随意修改容器,则应使用normal for循环(或while)。

如果要删除谓词返回true的元素,一个好方法是:

m_Connections.erase(
  std::remove_if(m_Connections.begin(),
                 m_Connections.end(),
                 [](Type elem) { return predicate(elem); }),
  m_Connections.end());

std::remove_if不会将迭代逻辑与谓词混合。

答案 2 :(得分:3)

如果要从容器中擦除元素,则需要迭代器。
并且您无法从元素本身获取迭代器 - 即使您可以,例如使用vector,基于范围的内部使用的迭代器将在下一步中失效,从而导致未定义的行为点。

所以答案是:不,在它的经典用法中你不能。基于范围的,仅用于方便迭代范围内的所有元素。

答案 3 :(得分:1)

将所有元素推入数组,然后执行弹出操作以删除项