Erase an stl element within the or loop
Hello
I have the ollowing for loops, inside the second for loop, i want to erase the second element based on some condition.
I know erasure invalidates the iterator. What is the nice way to do this ?
Code:
for (auto& sulCell : nCellList.sulCellList)
{
bool bFirstMatch = false;
for (auto& tddCell : nCellList.tddCellList)
{
if(condition)
erase(tddCell);
}
}
Re: Erase an stl element within the or loop
Quote:
Originally Posted by
pdk5
What is the nice way to do this ?
If the "list" is an STL container it comes with an erase() method which can be used to erase elements from the container. How to do it is described in the documentation for each container but as far as I know it's done in the same way for all containers using iterators and a for-loop. It means you cannot use the range-based for-loop you had in mind but that's the only change you have to make in principle.
This is the erase() documentation for std::list. See the "Erase all even numbers" example,
https://en.cppreference.com/w/cpp/container/list/erase
You can also go for the std-algorithms library. Then you end up using the Erase-Remove idiom:
https://en.wikipedia.org/wiki/Erase%...93remove_idiom
Re: Erase an stl element within the or loop
From the code in post #1, the outer loop seems irrelevant in the context of the question asked - as the control variable isn't used?
The important code is hence:
Code:
for (auto& tddCell : nCellList.tddCellList)
{
if(condition)
erase(tddCell);
}
This is a common requirement and, as Wolle says in post #2, there are 2 ways of doing this. As erase invalidates iterator(s) (and which depends upon the type of container used), no method can be used that uses implied iterators - such as range-for does.
Given a container c of numbers, the 2 methods are basically:
Code:
// Erase all even numbers
for (auto it = c.begin(); it != c.end(); )
if (*it % 2 == 0) // Condition for erasure
it = c.erase(it);
else
++it;
Note that there is no increment in the for statement. The iterator is only incremented if the erase condition is not true. If the element is erased, the return value from .erase() is the next element iterator (since C++11).
The other way is to use the Erase-Remove idiom:
Code:
c.erase(std::remove_if(c.begin(), c.end(), [](auto n){return n % 2 == 0;}), c.end());
where the lambda is the condition for removal.
The Erase-Remove is the recommended way of doing this, as .erase() is usually expensive as it may involve shuffling memory (depending upon the type of container).