expected<int, int>
isn't specified to be trivially assignableSection: 22.8.6.4 [expected.object.assign], 22.8.7.4 [expected.void.assign] Status: New Submitter: Barry Revzin Opened: 2025-01-21 Last modified: 2025-02-07
Priority: 2
View other active issues in [expected.object.assign].
View all other issues in [expected.object.assign].
View all issues with New status.
Discussion:
Currently, we specify that the copy constructor, move constructor, and destructor expected<int, int>
are trivial operations. But we do not specify that the copy assignment operator or move assignment operator are.
There is implementation divergence — MSVC's implementation is trivially copyable, but libstdc++'s and libc++'s
are not (although, they are trivial for the purposes of calls, which is important for being able to return such a
type in a register).
T
and E
are trivially
copy assignable and the move assignment operator is trivial if T
and E
are trivially move assignable.
[2025-02-07; Reflector poll]
Set priority to 2 after reflector poll.
"Needs to consider trivial constructors as well as assignment."
"This is an ABI break for something that shipped in C++23, NAD."
Proposed resolution:
This wording is relative to N5001.
Modify 22.8.6.4 [expected.object.assign] as indicated:
constexpr expected& operator=(const expected& rhs);-2- Effects: […]
-3- Returns:*this
. -4- Remarks: This operator is defined as deleted unless:
(4.1) — […]
(4.2) — […]
(4.3) — […]
(4.4) — […]
-?- This operator is trivial if
(?.1) —
is_trivially_copy_assignable_v<T>
istrue
and(?.2) —
is_trivially_copy_assignable_v<E>
istrue
.constexpr expected& operator=(expected&& rhs) noexcept(see below);-5- Constraints: […]
-6- Effects: […] -7- Returns:*this
. -8- Remarks: The exception specification is equivalent to:is_nothrow_move_assignable_v<T> && is_nothrow_move_constructible_v<T> && is_nothrow_move_assignable_v<E> && is_nothrow_move_constructible_v<E>-?- This operator is trivial if
(?.1) —
is_trivially_move_assignable_v<T>
istrue
and(?.2) —
is_trivially_move_assignable_v<E>
istrue
.
Modify 22.8.7.4 [expected.void.assign] as indicated:
constexpr expected& operator=(const expected& rhs);-1- Effects: […]
-2- Returns:*this
. -3- Remarks: This operator is defined as deleted unlessis_copy_assignable_v<E>
istrue
andis_copy_constructible_v<E>
istrue
. -?- This operator is trivial ifis_trivially_copy_assignable_v<E>
istrue
.constexpr expected& operator=(expected&& rhs) noexcept(see below);-4- Constraints: […]
-5- Effects: […] -6- Returns:*this
. -7- Remarks: The exception specification is equivalent tois_nothrow_move_constructible_v<E> && is_nothrow_move_assignable_v<E>
. -?- This operator is trivial ifis_trivially_move_assignable_v<E>
istrue
.