**Section:** 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:** 2023-12-22 11:09:04 UTC

**Priority: **Not Prioritized

**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.

**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>`is`true`, and(?.2) —

`is_trivially_copy_assignable_v<T>`is`true`, and(?.3) —

`is_trivially_destructible_v<T>`is`true`, and(?.4) —

`is_trivially_copy_constructible_v<E>`is`true`, and(?.5) —

`is_trivially_copy_assignable_v<E>`is`true`, and(?.6) —

`is_trivially_destructible_v<E>`is`true`.

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>`is`true`, and(?.2) —

`is_trivially_move_assignable_v<T>`is`true`, and(?.3) —

`is_trivially_destructible_v<T>`is`true`, and(?.4) —

`is_trivially_move_constructible_v<E>`is`true`, and(?.5) —

`is_trivially_move_assignable_v<E>`is`true`, and(?.6) —

`is_trivially_destructible_v<E>`is`true`.

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>`is`true`and`is_copy_constructible_v<E>`is`true`.-?- This operator is trivial if

`is_trivially_copy_constructible_v<E>`,`is_trivially_copy_assignable_v<E>`, and`is_trivially_destructible_v<E>`are all`true`.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>`is`true`and`is_move_assignable_v<E>`is`true`.-?- This operator is trivial if

`is_trivially_move_constructible_v<E>`,`is_trivially_move_assignable_v<E>`, and`is_trivially_destructible_v<E>`are all`true`.