It seems to be safe because your are using std::set
See http://www.cplusplus.com/reference/set/set/erase
Iterator validity:
Iterators, pointers and references referring to elements removed by the function are invalidated. All other iterators, pointers and references keep their validity.
The increment will happen before foo() is called, i.e. before the element is removed. In other words the increment is done while the iterator is valid and consequently it is safe. Note - that foo() is still called with the value the iterator had before the increment.
The fact that the increment happens before comes from this:
Quoth the [C++ standard][1] 1.9.16 (taken from the link below):
When calling a function (whether or
not the function is inline), every
value computation and side effect
associated with any argument
expression, or with the postfix
expression designating the called
function, is sequenced before
execution of every expression or
statement in the body of the called
function. (Note: Value computations
and side effects associated with the
different argument expressions are
unsequenced.)
Much more can be found here: Is it legal to use the increment operator in a C++ function call?