0

So I'm running through a list and erasing values that aren't divisible by 5 and 11. Right after I initialize an iterator to the beginning of a list, I assert if the iterator matches the beginning of the list, but it immediately fails. Why doesn't this work?

for(std::list<int>::iterator itr = numlist.begin(); itr != numlist.end(); itr++) {
    assert(itr == numlist.begin());
    if(*itr % 5 == 0 || *itr % 11 == 0) {
       itr = numlist.erase(itr);
   }
}
Duke K
  • 11
  • 3
  • 2
    Are you sure the `assert` occurs on the first iteration? – UnholySheep Feb 24 '18 at 17:45
  • 3
    I read my debugger wrong, I thought it was asserting on the first. Then the abort makes sense, thanks. – Duke K Feb 24 '18 at 17:47
  • 3
    Your assertion occurs on second loop iteration as expected. Not the first one. Chances are you are not stepping through your code one line at the time. – Ron Feb 24 '18 at 17:49
  • 2
    remember to pre-increment your iterator with ++itr instead of postincrement. – T33C Feb 24 '18 at 17:55
  • @T33C Why is that? – Passer By Feb 24 '18 at 18:02
  • 1
    Your code will crash if it happens to erase the last element in the list. `itr = numlist.erase(itr);` will set `itr` to `end()`, then the loop increments the iterator. Hillarity ensues. – Sam Varshavchik Feb 24 '18 at 18:04
  • @PasserBy https://stackoverflow.com/questions/24901/is-there-a-performance-difference-between-i-and-i-in-c – T33C Feb 24 '18 at 18:09
  • 1
    use lists remove_if method – T33C Feb 24 '18 at 18:09
  • @T33C Yeah, no. That is plain myth. [Optimizers doesn't suck that much](https://godbolt.org/g/4m1WxX) – Passer By Feb 24 '18 at 18:13
  • 1
    @PasserBy it is best to choose the correct semantics rather than relying on the optimiser because in some cases there will be a side effect that can't be optimised away. Also, it creates uncertainty whether the optimiser has indeed been able to optimise. This wastes time in reviews and future maintenance. – T33C Feb 24 '18 at 19:32

0 Answers0