std::expected
should propagate trivialitySection: 22.8.6.4 [expected.object.assign], 22.8.7.4 [expected.void.assign] Status: New Submitter: Jiang An Opened: 2023-12-16 Last modified: 2024-03-11
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, only copy and move constructors of std::expected
are required to propagate triviality,
while copy and move assignment operators are not. Given that the assignment operators of std::optional
and std::variant
are already required to propagate triviality, it seems to me that we should also
apply such requirements for std::expected
.
Such changes are being made in libc++ (llvm/llvm-project#74768). And it may be desired to make the triviality improvement portable.
[2024-03-11; Reflector poll]
Set priority to 2 after reflector poll in January 2024. A few votes for Tentatively Ready, others thought it needed more consideration.
Proposed resolution:
This wording is relative to N4971.
Modify 22.8.6.4 [expected.object.assign] as indicated:
constexpr expected& operator=(const expected& rhs);-2- Effects: […]
[…]
-4- Remarks: This operator is defined as deleted unless:
[…]
-?- This operator is trivial if:
(?.1) —
is_trivially_copy_constructible_v<T>
istrue
, and(?.2) —
is_trivially_copy_assignable_v<T>
istrue
, and(?.3) —
is_trivially_destructible_v<T>
istrue
, and(?.4) —
is_trivially_copy_constructible_v<E>
istrue
, and(?.5) —
is_trivially_copy_assignable_v<E>
istrue
, and(?.6) —
is_trivially_destructible_v<E>
istrue
.constexpr expected& operator=(expected&& rhs) noexcept(see below);-5- Constraints: […]
[…]
-8- Remarks: The exception specification is equivalent to:
[…]
-?- This operator is trivial if:
(?.1) —
is_trivially_move_constructible_v<T>
istrue
, and(?.2) —
is_trivially_move_assignable_v<T>
istrue
, and(?.3) —
is_trivially_destructible_v<T>
istrue
, and(?.4) —
is_trivially_move_constructible_v<E>
istrue
, and(?.5) —
is_trivially_move_assignable_v<E>
istrue
, and(?.6) —
is_trivially_destructible_v<E>
istrue
.
Modify 22.8.7.4 [expected.void.assign] as indicated:
constexpr expected& operator=(const expected& rhs);-1- Effects: […]
[…]
-3- Remarks: This operator is defined as deleted unless
is_copy_assignable_v<E>
istrue
andis_copy_constructible_v<E>
istrue
.-?- This operator is trivial if
is_trivially_copy_constructible_v<E>
,is_trivially_copy_assignable_v<E>
, andis_trivially_destructible_v<E>
are alltrue
.constexpr expected& operator=(expected&& rhs) noexcept(see below);-4- Effects: […]
[…]
-6- Remarks: The exception specification is equivalent to
is_nothrow_move_constructible_v<E> && is_nothrow_move_assignable_v<E>
.-7- This operator is defined as deleted unless
is_move_constructible_v<E>
istrue
andis_move_assignable_v<E>
istrue
.-?- This operator is trivial if
is_trivially_move_constructible_v<E>
,is_trivially_move_assignable_v<E>
, andis_trivially_destructible_v<E>
are alltrue
.