https://gcc.gnu.org/bugzilla/show_bug.cgi?id=112307
--- Comment #9 from Jonathan Wakely <redi at gcc dot gnu.org> --- Ironically, writing a user-provided (and so non-trivial) copy constructor which fixes up the self-referential pointer (or iterator, in your case) will restore guaranteed elision, and that copy constructor isn't actually used. But with a trivial copy constructor, your object gets copied, and the self-referential pointer gets invalidated because it points to a temporary that has gone out of scope, not to the final object after the copies are done.