Can you remove elements from a std::list while iterating through it?

后端 未结 13 1040
长情又很酷
长情又很酷 2020-11-22 06:30

I\'ve got code that looks like this:

for (std::list::iterator i=items.begin();i!=items.end();i++)
{
    bool isActive = (*i)->update();
    /         


        
13条回答
  •  滥情空心
    2020-11-22 06:33

    You can write

    std::list::iterator i = items.begin();
    while (i != items.end())
    {
        bool isActive = (*i)->update();
        if (!isActive) {
            i = items.erase(i); 
        } else {
            other_code_involving(*i);
            i++;
        }
    }
    

    You can write equivalent code with std::list::remove_if, which is less verbose and more explicit

    items.remove_if([] (item*i) {
        bool isActive = (*i)->update();
        if (!isActive) 
            return true;
    
        other_code_involving(*i);
        return false;
    });
    

    The std::vector::erase std::remove_if idiom should be used when items is a vector instead of a list to keep compexity at O(n) - or in case you write generic code and items might be a container with no effective way to erase single items (like a vector)

    items.erase(std::remove_if(begin(items), end(items), [] (item*i) {
        bool isActive = (*i)->update();
        if (!isActive) 
            return true;
    
        other_code_involving(*i);
        return false;
    }));
    

提交回复
热议问题