首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >在位删除图元的最佳方法

在位删除图元的最佳方法
EN

Stack Overflow用户
提问于 2008-12-09 16:09:12
回答 3查看 1.4K关注 0票数 2

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

我的代码如下:

代码语言:javascript
运行
复制
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();
            }

        }


    }

当然,当我擦除一个对象时,我得到一个错误:"Map / set iterator not incrementable“。有没有人能推荐一种更好的方法呢?

请参阅:What happens if you call erase() on a map element while iterating from begin to end?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2008-12-09 16:18:09

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

map的一个简单方法是将要擦除的项目累积到一个单独的列表中,然后在完成对map的处理后遍历该列表以从map中擦除这些项目。这假设您可以将删除操作推迟到小版本完成。如果不是,那么您别无选择,只能在每次删除时重新启动迭代。

票数 6
EN

Stack Overflow用户

发布于 2008-12-09 16:39:51

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

代码语言:javascript
运行
复制
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实际上是它的成员函数)访问m_Container,并且其结果取决于容器的内容,那么我的代码可能不等同于提问者的代码。但我认为我的代码是默认的“除非有理由不这样做”。

票数 6
EN

Stack Overflow用户

发布于 2008-12-09 16:30:45

已通过以下方式修复:

代码语言:javascript
运行
复制
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++,我们可以绕过它。感谢那些发表建议的人。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/353296

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档