Erasing item in a for(-each) auto loop

浪尽此生 提交于 2019-11-29 04:51:24

No, there isn't. Range based for loop is used to access each element of a container once.

Every time an element is removed from the container, iterators at or after the erased element are no longer valid (and given the implementation of the range-based-for this is a problem).

You should use the normal for loop (or a while) if you need to modify the container as you go along.

If you want to erase elements for which a predicate returns true, a good way is:

m_Connections.erase(
  std::remove_if(m_Connections.begin(),
                 m_Connections.end(),
                 [](Type elem) { return predicate(elem); }),
  m_Connections.end());

std::remove_if doesn't mix iteration logic with the predicate.

You can't. A range-based loop makes a simple iteration over a range simpler, but doesn't support anything that invalidates either the range, or the iterator it uses. Of course, even if that were supported, you couldn't efficiently erase an element without access to the iterator.

You'll need an old-school loop, along the lines of

for (auto it = container.begin(); it != container.end();) {
    if (something) {
        it = container.erase(it);
    } else {
        ++it;
    }
}

or a combination of container.erase() and std::remove_if, if you like that sort of thing.

You need the iterator if you want to erase an element from a container.
And you can't get the iterator from the element itself -- and even if you could, for instance with vector, the iterator that range-based for internally uses would be invalidated in the next step causing undefined behavior.

So the answer is: No, in its classic usage you can't. range-based for was solely designed for convenient iteration of all elements in a range.

push all elements into array and then do pop operation to remove the item

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!