title: Deleting elements from std::set while iterating
body: <p>I need to go through a set and remove elements that meet a predefined criteria.</p>
  
  <p>This is the test code I wrote:</p>
  
  <pre><code>#include &lt;set&gt;
  #include &lt;algorithm&gt;
  
  void printElement(int value) {
      std::cout &lt;&lt; value &lt;&lt; " ";
  }
  
  int main() {
      int initNum[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
      std::set&lt;int&gt; numbers(initNum, initNum + 10);
      // print '0 1 2 3 4 5 6 7 8 9'
      std::for_each(numbers.begin(), numbers.end(), printElement);
  
      std::set&lt;int&gt;::iterator it = numbers.begin();
  
      // iterate through the set and erase all even numbers
      for (; it != numbers.end(); ++it) {
          int n = *it;
          if (n % 2 == 0) {
              // wouldn't invalidate the iterator?
              numbers.erase(it);
          }
      }
  
      // print '1 3 5 7 9'
      std::for_each(numbers.begin(), numbers.end(), printElement);
  
      return 0;
  }
  </code></pre>
  
  <p>At first, I thought that erasing an element from the set while iterating through it would invalidate the iterator, and the increment at the for loop would have undefined behavior. Even though, I executed this test code and all went well, and I can't explain why.</p>
  
  <p><strong>My question:</strong>
  Is this the defined behavior for std sets or is this implementation specific? I am using gcc 4.3.3 on ubuntu 10.04 (32-bit version), by the way.</p>
  
  <p>Thanks!</p>
  
  <p><strong>Proposed solution:</strong></p>
  
  <p>Is this a correct way to iterate and erase elements from the set?</p>
  
  <pre><code>while(it != numbers.end()) {
      int n = *it;
      if (n % 2 == 0) {
          // post-increment operator returns a copy, then increment
          numbers.erase(it++);
      } else {
          // pre-increment operator increments, then return
          ++it;
      }
  }
  </code></pre>
  
  <p><strong>Edit: PREFERED SOLUTION</strong></p>
  
  <p>I came around a solution that seems more elegant to me, even though it does exactly the same.</p>
  
  <pre><code>while(it != numbers.end()) {
      // copy the current iterator then increment it
      std::set&lt;int&gt;::iterator current = it++;
      int n = *current;
      if (n % 2 == 0) {
          // don't invalidate iterator it, because it is already
          // pointing to the next element
          numbers.erase(current);
      }
  }
  </code></pre>
  
  <p>If there are several test conditions inside the while, each one of them must increment the iterator. I like this code better because the iterator is incremented <strong>only in one place</strong>, making the code less error-prone and more readable.</p>