1

Very simple: I have the following code and the method erase is not working. I do not see any problem there because if I go to http://www.cplusplus.com/reference/list/list/erase/ , syntax is: iterator erase (iterator position);

list<pair<string,int>> l0 { { "name1", 20 }, { "name2", 30 }, { "name3", 40 } };
for( auto &it : l0 )
    l0 . erase( it );

May there be a problem that there is a list of pair<string,int> and not a list of a basic data types?

EDIT: The problem is that the code is not compilable.

scarface
  • 574
  • 6
  • 20

2 Answers2

2

The range-for iterates through a container by giving you access to the elements in the container, and not an iterator to an element.

So in for( auto &it : l0 ), it isn't an iterator to a pair but a reference to a pair. This is why your code doesn't compile

This being said, as πάνταῥεῖ pointed out when he initially closed this as a duplicate of Keeping a valid vector::iterator after erase(), even if your code would compile it wouldn't work because of the invalidation of the iterator following the erase:

Iterators, pointers and references referring to elements removed by the function are invalidated. All other iterators, pointers and references keep their validity.

Workaround

You shall not use the range-for, but the traditional for, and iterating using the return value of erase() :

for (auto it=l0.begin(); it!=l0.end(); ) 
    it = l0.erase(it);  // to avoid incrementing an invalidated iterator

Live demo

Community
  • 1
  • 1
Christophe
  • 68,716
  • 7
  • 72
  • 138
  • This answer is wrong. Only every second element will be erased (also it may literate past the end). –  Apr 24 '16 at 13:24
  • @DieterLücking can you elaborate ? Because the live demo shows something that seems to works perfectly (the return value of erase() being "*An iterator pointing to the element that followed the last element erased by the function call. This is the container end if the operation erased the last element in the sequence.*". – Christophe Apr 24 '16 at 13:34
2

The answer above given by Christophe is perfect and that helped me as well. I came up with something like this (I had some other requirement). I hope this can help someone for sure. You can use remove_if command for achieving something similar.

//Suppose user wants to remove the entry with fits value as "name1"

l0.remove_if([key](auto it) { 
    return it.first == "name1"; 
});
Mazhar MIK
  • 1,022
  • 12
  • 14