Erase one element in vector in 'for' cycle

Below are some code which use erase in 'for' cycle.
It want to remove a element which meet the condition.
typedef std::vector<struct pollfd> PollFdList;
PollFdList poll_fds_;

for (PollFdList::iterator pfd = poll_fds_.begin(); pfd != poll_fds_.end(); ++pfd)
{
if (pfd->fd == fd)
{
poll_fds_.erase(pfd);
break;
}
}

Does the code work?, i.e. there is no logic error?
I am not sure about this.

I think a better way is like below:
for (PollFdList::iterator pfd = poll_fds_.begin(); pfd != poll_fds_.end(); ++pfd)
{
if (pfd->fd == fd)
{
pfd = poll_fds_.erase(pfd);
break;
}
}
The difference between them is the iterator pfd is explictly updated to point to the new location of the element that followed the last element erased by the function call.

Am I right?
Does the first way work?

Last edited on
> Does the first way work?

Yes.
The iterator pfd is invalidated by poll_fds_.erase(pfd);
after that, if we evaluate ++pfd it would engender undefined behaviour.
However, because of the break immediately after the call to erase(), the invalidated iterator is never used again; this is therefore fine.

Consider using the erase-remove idiom if more than one element which meets a condition is to be removed.
https://en.wikipedia.org/wiki/Erase%E2%80%93remove_idiom
Last edited on
oh, I see. thank you very much.

Then, if more than one element which meets a condition is to be removed.
It can be implemented as below.
I think it is OK?

PollFdList::iterator pfd = poll_fds_.begin();
while( pfd != poll_fds_.end())
{
if (pfd->fd == fd)
{
pfd=poll_fds_.erase(pfd);
}
else
{
++pfd;
}
}
> I think it is OK?

Yes.


This would be the idiomatic way of doing the same thing:
https://en.wikipedia.org/wiki/Erase%E2%80%93remove_idiom

1
2
3
4
 // http://en.cppreference.com/w/cpp/algorithm/remove
const auto erase_from_here = std::remove_if( poll_fds_.begin(), poll_fds_.end(), 
                                             [] ( const auto& pollfd ) { return pollfd.fd == fd ; } ) ;
poll_fds_.erase( erase_from_here, poll_fds_.end() ) ;

Last edited on
Topic archived. No new replies allowed.