This page is a snapshot from the LWG issues list, see the Library Active Issues List for more information and the meaning of NAD status.
std::swap
are under-specifiedSection: 22.2.2 [utility.swap] Status: NAD Submitter: Jan Schultke Opened: 2024-02-28 Last modified: 2024-06-24
Priority: Not Prioritized
View all other issues in [utility.swap].
View all issues with NAD status.
Discussion:
Subclause 22.2.2 [utility.swap] describes the effect of std::swap
as follows:
Effects: Exchanges values stored in two locations.
This description is extremely vague. A possible implementation which complies with this wording is:
template<class T> constexpr void swap(T&, T&) noexcept(/* ... */) { int __x = 0, __y = 0; int __z = __x; __x = __y; __y = __z; }
This exchanges values stored in two locations; namely in the locations of two objects with automatic
storage duration within swap
. Since this has no observable effect and complies, it is also
valid to implement swap
as follows:
template<class T> constexpr void swap(T&, T&) noexcept(/* ... */) { }
Furthermore, there is implementation divergence.
libc++ uses direct-initialization to construct a temporary T
, but
libstdc++ uses copy-initialization. For most types, this hopefully calls the same constructor, however,
this is not universally true. The standard should specify in more detail what is meant to happen.
[2024-03-15; Reflector poll]
Set status to Tentatively NAD Editorial after reflector poll.
Cpp17MoveConstructible require direct-init and copy-init to be semantically equivalent, so the different implementation techniques can only be observed by types which fail to meet the function's preconditions.
Replace the unusual "stored in two locations" wording editorially.
[St. Louis 2024-06-24 Status changed: Tentatively NAD → NAD.]
Proposed resolution:
This wording is relative to N4971.
Modify 22.2.2 [utility.swap] as indicated:
template<class T> constexpr void swap(T& a, T& b) noexcept(see below);-1- Constraints:
-2-Preconditions: Typeis_move_constructible_v<T>
istrue
andis_move_assignable_v<T>
istrue
.T
meets the Cpp17MoveConstructible (Table 31) and Cpp17MoveAssignable (Table 33) requirements. -3- Effects:Exchanges values stored in two locations.Equivalent to:auto t(std::move(a)); a = std::move(b); b = std::move(t);-4- Remarks: The exception specification is equivalent to: […]