2

我有一组要迭代的对象,但是我可能会在迭代期间决定现在需要删除这些对象中的一个(或多个)。

我的代码如下:

if( ! m_Container.empty() )
    {
        for(  typedefedcontainer::iterator it = m_Container.begin();
              it != m_Container.end(); 
              ++it  )
        {
            if( ! ( SomeFunction( (*it), "test", "TEST!", false ))  )
            {
            // If function returns false, delete object.
                m_Container.erase( it );
                AsyncResponseStore::iterator it = m_asyncResponses.begin();
            }

        }


    }

但是,当然,当我擦除一个对象时,我得到一个错误:“映射/设置迭代器不可增加”。有人可以提出更好的方法吗?

请参阅: 如果在从头到尾迭代时在地图元素上调用 erase() 会发生什么?

4

3 回答 3

6

这取决于容器。列表容器通过从代表列表中下一项的擦除方法返回一个新的迭代器来支持枚举期间的删除。地图不支持这个。

map 的一种简单方法是将要擦除的项目累积在一个单独的列表中,然后在完成处理映射以从映射中擦除项目时迭代该列表。这假设您可以推迟删除,直到迭代完成。如果没有,那么您别无选择,只能为每次删除重新启动迭代。

于 2008-12-09T16:18:08.920 回答
6

如果容器支持它(我怀疑你的不支持,但问题标题是通用的,所以如果不是你,这可能对其他人有用):

struct SomePredicate {
    bool operator()(typedefedcontainer::value_type thing) {
        return ! SomeFunction(thing, "test", "TEST", false);
    }
};

typedefedcontainer::iterator it;
it = std::remove_if(m_Container.begin(), m_Container.end(), SomePredicate());
m_Container.erase(it, m_Container.end());

m_Container 必须有一个擦除范围方法,它包括任何序列或关联容器。不过,它确实必须有一个可变迭代器,我只是注意到我最初误读了错误消息:它说“map / set iterator not incrementable”。所以我猜你的容器是一张地图或一套。

请注意,最后三个可能是一个真正了不起的单行,但这个边距太窄而无法包含它。

此外,SomePredicate 可以有一个带有参数的构造函数来将附加参数存储到 SomeFunction,因为在现实生活中我猜它们是非常量的。

如果你使用 boost:bind 来构造函子,你实际上可以完全摆脱 SomePredicate 。然后,您的单线将非常庞大。

[编辑:Rob Walker 在他的回答中正确地指出了我在这里所做的假设并且问题没有说明,即所有擦除都可以推迟到迭代和测试完成之后。如果 SomeFunction 通过隐藏路由(例如全局,或者因为 SomeFunction 实际上是 this 的成员函数)访问 m_Container,并且其结果取决于容器的内容,那么我的代码可能不等同于提问者的代码。但我认为我的代码是“除非有理由不”默认。]

于 2008-12-09T16:39:51.433 回答
0

通过以下方式修复:

for(  typedefedcontainer::iterator it = m_Container.begin();
      it != m_Container.end(); 
        )
{
    if( ! ( SomeFunction( (*it), "test", "TEST!", false ))  )
    {
    // If function returns false, delete object.
        m_Container.erase( it++ );
    }
    else
    { 
        ++i;
    } 

}

当一个元素被删除时,所有指向它的指针都会失效。因此,通过使用 it++,我们可以绕过它。感谢那些发布建议的人。

于 2008-12-09T16:30:45.400 回答