Erase one element in vector in 'for' cycle

Jul 30, 2017 at 3:19am
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 Jul 30, 2017 at 3:20am
Jul 30, 2017 at 3:28am
> 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 Jul 30, 2017 at 3:34am
Jul 30, 2017 at 6:56am
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;
}
}
Jul 30, 2017 at 11:13am
> 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 Jul 30, 2017 at 11:47am
Topic archived. No new replies allowed.