I think I figured it out myself. Visual C++ seems to be correct, and Clang and GCC seem to be wrong.
It's because swap
should not invalidate iterators for std::set
or std::map
. If we try this code:
#include <set>
#include <iostream>
int main()
{
std::set<int> a, b;
std::set<int>::iterator end = a.end();
a.swap(b);
b.insert(end, 1);
std::cout << b.size() << std::endl;
return 0;
}
If the head of the tree was stored on the stack, then end
would become invalidated after the swap.
Visual C++ handles it just fine, but GCC and Clang loop infinitely (at least on my versions).
Edit: The above may have been the reason until C++03 due to an ambiguity, but it is no longer the case since C++11 -- please see the comments below.