On Wed, Apr 28, 2021 at 5:40 PM Giuseppe D'Angelo via Std-Discussion <std-discussion@lists.isocpp.org> wrote:
Hello,

On 28/04/2021 16:55, Christopher Hallock via Std-Discussion wrote:
>         This kind of Library provision, saying that iterators, pointers,
>         and references to elements are invalidated upon condition X,
>         seems overly broad even if you don't care about using pointers
>         in an "index-like" way, because it means you can't safely use an
>         element type that stores (and properly updates across
>         moves/copies) the 'this' pointer as a member. I suspect that the
>         real intent of this kind of provision is that it only applies to
>         iterators, pointers, and references obtained through the
>         container's API.
>
>
>     Gah, never mind. On further reflection, this is not actually a
>     problem because the member would be overwritten on copy/move.
>
>
>   On even further reflection, I retract my retraction. It would
> definitely be a problem if the invalidation occurs after the elements
> are moved/copied. It would also be a problem if the invalidation occurs
> beforehand and the move/copy operation involves indirecting through the
> original element's pointer member.

Apologies; I'm not sure if I understand the counter-counter objection.

I was definitely talking about pointers obtained via the container's own
APIs (data(), or & + operator[]/at(), &*it, etc.), and not pointers that
the stored objects might be tracking themselves (for instance by adding
themselves to some external "registry", or by having a member pointer
equal to `this`, or so.).

Is the objection related about "what happens if the objects stored in
the container use container-API-derived pointers from their
constructors, assignment operators etc. WHILE the container is
performing a modification -- insertion, erasure, etc."?

I was adding my own concerns about these library clauses being underspecified and overly broad. Getting back to your original question, which is whether library invalidation "sticks", given [basic.life]/8: I believe it does. If the invalidating operation move-assigns or copy-assigns the elements, then [basic.life]/8 doesn't even apply because no new object was created. If the invalidating operation move-constructs or copy-constructs the elements, then there is room for ambiguity, but I think the intent is that even in this case, the invalidation "sticks". I believe things happen in this sequence: 1) element is destroyed, which automatically invalidates pointers to it; 2) new element is created in the same place, "resurrecting" the old pointers via [basic.life]/8; 3) the library clause kicks in and invalidates the resurrected pointers once more.