2321. Moving containers should (usually) be required to preserve iterators

Section: 23.2.2 [container.requirements.general] Status: Open Submitter: Stephan T. Lavavej Opened: 2013-09-21 Last modified: 2023-01-20

Priority: 3

View other active issues in [container.requirements.general].

View all other issues in [container.requirements.general].

View all issues with Open status.

Discussion:

23.2.2 [container.requirements.general]/10 says that unless otherwise specified, "no swap() function invalidates any references, pointers, or iterators referring to the elements of the containers being swapped. [Note: The end() iterator does not refer to any element, so it may be invalidated. — end note]". However, move constructors and move assignment operators aren't given similar invalidation guarantees. The guarantees need several exceptions, so I do not believe that blanket language like /11 "Unless otherwise specified (either explicitly or by defining a function in terms of other functions), invoking a container member function or passing a container as an argument to a library function shall not invalidate iterators to, or change the values of, objects within that container." is applicable.

[2014-02-13 Issaquah]

General agreeement on intent, several wording nits and additional paragraphs to hit.

STL to provide updated wording. Move to Open.

[2015-02 Cologne]

AM: in the proposed wording, I'd like to mention that the iterators now refer to elements of a different container. I think we're saying something like this somewhere. JY: There's some wording like that for swap I think. TK: It's also in list::splice(). DK to JY: 23.2.1p9.

VV: The issue says that STL was going to propose new wording. Has he done that? AM: I believe we're looking at that. GR: The request touches on multiple paragraphs, and this PR has only one new paragraph, so this looks like it's not up-to-date. MC: This was last updated a year ago in Issaquah.

Conclusion: Skip, not up to date.

[2015-06, Telecon]

Still waiting for updated wording

[2015-08 Chicago]

Still waiting for updated wording

[2018-08-23 Batavia Issues processing]

Priority to 3

[2023-01-20; std-proposals post]

Emile Cormier observed that the proposed resolution of this issue contradicts with changes made by LWG 2839. Specifially, the current draft does not require container elements to be preserved on self-move-assignment. If this issue is accepted, it would either need to allow iterator invalidation on self-move-assignment or remove the "If a and rv do not refer to the same object" changes added to the container requirements by LWG 2839.

Proposed resolution:

This wording is relative to N3691.

  1. In 23.2.2 [container.requirements.general]/10 change as indicated:

    -10- Unless otherwise specified (see 23.2.4.1, 23.2.5.1, 23.3.3.4, and 23.3.7.5) all container types defined in this Clause meet the following additional requirements:

    • […]

    • no copy constructor or assignment operator of a returned iterator throws an exception.

    • no move constructor (or move assignment operator when allocator_traits<allocator_type>::propagate_on_container_move_assignment::value is true) of a container (except for array) invalidates any references, pointers, or iterators referring to the elements of the source container. [Note: The end() iterator does not refer to any element, so it may be invalidated. — end note]

    • no swap() function throws an exception.

    • no swap() function invalidates any references, pointers, or iterators referring to the elements of the containers being swapped. [Note: The end() iterator does not refer to any element, so it may be invalidated. — end note]