Title
expected<int, int> isn't specified to be trivially assignable
Status
new
Section
[expected.object.assign][expected.void.assign]
Submitter
Barry Revzin

Created on 2025-01-21.00:00:00 last changed 1 week ago

Messages

Date: 2025-01-25.14:23:29

Proposed resolution:

This wording is relative to N5001.

  1. Modify [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:

    1. (4.1) — […]

    2. (4.2) — […]

    3. (4.3) — […]

    4. (4.4) — […]

    -?- This operator is trivial if

    1. (?.1) — is_trivially_copy_assignable_v<T> is true and

    2. (?.2) — is_trivially_copy_assignable_v<E> is true.

    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. (?.1) — is_trivially_move_assignable_v<T> is true and

    2. (?.2) — is_trivially_move_assignable_v<E> is true.

  2. Modify [expected.void.assign] as indicated:

    constexpr expected& operator=(const expected& rhs);
    

    -1- Effects: […]

    -2- Returns: *this.

    -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_assignable_v<E> is true.

    constexpr expected& operator=(expected&& rhs) noexcept(see below);
    

    -4- Constraints: […]

    -5- Effects: […]

    -6- Returns: *this.

    -7- Remarks: The exception specification is equivalent to is_nothrow_move_constructible_v<E> && is_nothrow_move_assignable_v<E>.

    -?- This operator is trivial if is_trivially_move_assignable_v<E> is true.

Date: 2025-01-21.00:00:00

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

I'm not sure there is any reason the assignment operators should not be trivial here. We should add the same kind of remarks in both cases: that the copy assignment operator is trivial if T and E are trivially copy assignable and the move assignment operator is trivial if T and E are trivially move assignable.

History
Date User Action Args
2025-01-25 14:23:29adminsetmessages: + msg14547
2025-01-21 00:00:00admincreate