Section: 220.127.116.11 [lib.types.movedfrom], 18.104.22.168 [res.on.arguments], 26.2.1 [container.requirements.general] Status: New Submitter: Tim Song Opened: 2016-12-09 Last modified: 2017-02-02
View all issues with New status.
LWG 2468's resolution added to MoveAssignable the requirement to tolerate self-move-assignment, but that does nothing for library types that aren't explicitly specified to meet MoveAssignable other than make those types not meet MoveAssignable any longer.To realize the intent here, we need to carve out an exception to 22.214.171.124 [res.on.arguments]'s restriction for move assignment operators and specify that self-move-assignment results in valid but unspecified state unless otherwise specified. The proposed wording below adds that to 126.96.36.199 [lib.types.movedfrom] since it seems to fit well with the theme of the current paragraph in that section. In addition, to address the issue with 26.2.1 [container.requirements.general] noted in LWG 2468's discussion, the requirement tables in that subclause will need to be edited in a way similar to LWG 2468.
This wording is relative to N4618.
Add a new paragraph at the end of 188.8.131.52 [lib.types.movedfrom]:
-1- Objects of types defined in the C++ standard library may be moved from (12.8). Move operations may be explicitly specified or implicitly generated. Unless otherwise specified, such moved-from objects shall be placed in a valid but unspecified state.
Add a note at the end of 184.108.40.206 [res.on.arguments]/1, bullet 3, as indicated:
-1- Each of the following applies to all arguments to functions defined in the C++ standard library, unless explicitly stated otherwise.
(1.1) — […]
(1.2) — […]
(1.3) — If a function argument binds to an rvalue reference parameter, the implementation may assume that this parameter is a unique reference to this argument. [Note: If the parameter is a generic parameter of the form T&& and an lvalue of type A is bound, the argument binds to an lvalue reference (220.127.116.11) and thus is not covered by the previous sentence. — end note] [Note: If a program casts an lvalue to an xvalue while passing that lvalue to a library function (e.g. by calling the function with the argument std::move(x)), the program is effectively asking that function to treat that lvalue as a temporary. The implementation is free to optimize away aliasing checks which might be needed if the argument was an lvalue. — end note]
Edit Table 83 "Container requirements" in 26.2.1 [container.requirements.general] as indicated:
Table 83 — Container requirements Expression Return type Operational
Complexity … a = rv T& All existing elements of a
are either move
assigned to or
a shall be equal to the value that
rv had before this assignment
Edit Table 86 "Allocator-aware container requirements" in 26.2.1 [container.requirements.general] as indicated:
Table 86 — Allocator-aware container requirements Expression Return type Assertion/note
Complexity … a = rv T& Requires: If allocator_traits<allocator_type
is false, T is MoveInsertable
into X and MoveAssignable.
All existing elements of a are either
move assigned to or destroyed.
post: a shall be equal
to the value that rv had before this assignment