Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to erase elements of a std::list in a c++11 for each loop

Tags:

c++

c++11

stl

I want to use the new C++11 for each loop to iterate over all elements of a list and erase certains elements. For example

std::list<int> myList;
myList.push_back(1); 
myList.push_back(13);
myList.push_back(9);
myList.push_back(4);

for(int element : myList) {
    if(element > 5) {
        //Do something with the element

        //erase the element
    }else{
        //Do something else with the element
    }
}

Is it possible to do this using the for each loop or do I have to go back to iterators to achive this?

like image 829
Haatschii Avatar asked Jan 13 '13 15:01

Haatschii


People also ask

How do I remove multiple elements from a list in C++?

Using list::erase(): The purpose of this function is to remove the elements from list. Single or multiple contiguous elements in range can be removed using this function. This function takes 2 arguments, start iterator and end iterator.

How do I remove something from a list in C++?

remove() is an inbuilt function in C++ STL which is declared in header file. remove() is used to remove any specific value/element from the list container. It takes the value which is passed as a parameter and removes all the elements with that value from the list container.

How do you remove an element from a vector in C++?

The C++ vector has many member functions. Two of these member functions are erase() and pop_back(). pop_back() removes the last element from the vector. In order to remove all the elements from the vector, using pop_back(), the pop_back() function has to be repeated the number of times there are elements.


2 Answers

You should be able to just do this

myList.erase(std::remove_if(myList.begin(), myList.end(),
    [](int& element) 
    { 
        return element > 5;
    } 
    ),myList.end());

or simply (courtesy Benjamin Lindley)

myList.remove_if(
    [](int& element) 
    { 
        return element > 5;
    } 
    );
like image 110
Karthik T Avatar answered Oct 21 '22 06:10

Karthik T


You can't erase elements of standard containers in a range-based for loop over that container -- the loop itself has an iterator to the element that you're currently visiting, and erasing it would invalidate that iterator before the loop increments it.

Range-based for is defined in 6.5.4 of the standard to be equivalent to (slightly simplified):

for (auto __begin=begin-expr, __end=end-expr; __begin != __end; ++__begin) {
    for-range-declaration = *__begin;
    statement
}

begin-expr and end-expr have their own lengthy definition, but in your example they are myList.begin() and myList.end() respectively.

like image 21
Steve Jessop Avatar answered Oct 21 '22 05:10

Steve Jessop