Search code examples
c++c++11iteratorunordered-set

Is it well-defined to modify an unordered_set inside a foreach loop if one breaks out immediately after?


Consider the following program. The loop in the middle attempts to replace exactly one item with one other item, and then breaks out of the loop.

#include <unordered_set>
#include <stdio.h>

int main(){
    std::unordered_set<int> foo{1,2,3};
    printf("Set Before:\n");
    for (int x : foo)
        printf("%d\n", x);
    for (int x : foo) {
        if (x == 1) {
            foo.erase(1);
            foo.insert(4);
            break;
        }
    }
    printf("Set After:\n");
    for (int x : foo)
        printf("%d\n", x);
}

Is the code above well-defined?


Solution

  • Is the code above well-defined?

    Yes. The erase would invalidate the iterator you're on right now, which would make the subsequent increment of it undefined behavior - but there is no subsequent increment, since you're breaking unconditionally.


    Although instead of looping over each element until you find 1, you can just try to erase it and see if that did anything:

    if (foo.erase(1)) {
        foo.insert(4);
    }