luka25's blog

By luka25, history, 9 years ago, In English

I just tried to delete some members from set while iterating with this code:

while(*it<=b){ if(*it!=x){m[*it]=x;s.erase(it);} else it++; }

I found out the right one was this, but can't figure out why

while(*it<=b){ if(*it!=x){m[*it]=x;s.erase(it++);} else it++; }

could anybody explain why it++ instead of it please?

  • Vote: I like it
  • +6
  • Vote: I do not like it

»
9 years ago, # |
Rev. 4   Vote: I like it +4 Vote: I do not like it

Because if you look into set documentation erase method you'll find the following:

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

so s.erase(it) invalides it.

s.erase(it++) works, because it++ returns copy of iterator. For example,++it wouldn't work.

  • »
    »
    9 years ago, # ^ |
    Rev. 2   Vote: I like it +9 Vote: I do not like it

    any code with postfix operators is undefined behavior waiting to happen. The only proper way to do it is
    it = s.erase(it)

    • »
      »
      »
      9 years ago, # ^ |
        Vote: I like it 0 Vote: I do not like it

      how it=s.erase(it)?I can't write that

    • »
      »
      »
      9 years ago, # ^ |
        Vote: I like it +1 Vote: I do not like it

      Are you sure?

      All function parameters must be fully evaluated before function call — this is one of few rules you can be sure of in expression evaluation.

      So it++ must be fully evaluated before function call. Which means that there should be two copies of it — one incremented, which becomes it going forward and one copy not incremented, which is provided to the function and afterwards deleted.

      What can cause troubles?

      Also it = s.erase(it) is only C++11.

  • »
    »
    9 years ago, # ^ |
      Vote: I like it 0 Vote: I do not like it

    Thanks for reply, I get it now, but would be more logical first way to me.