3687. expected<cv void, E> move constructor should move

Section: 22.8.7.4 [expected.void.assign] Status: C++23 Submitter: Jonathan Wakely Opened: 2022-03-23 Last modified: 2023-11-22

Priority: Not Prioritized

View all other issues in [expected.void.assign].

View all issues with C++23 status.

Discussion:

For expected<cv void>::operator=(expected&&) we have this in the last bullet of the Effects element:

Otherwise, equivalent to unex = rhs.error().

That should be a move assignment, not a copy assignment.

[2022-05-17; Reflector poll]

Set status to Tentatively Ready after eight votes in favour during reflector poll.

[2022-07-15; LWG telecon: move to Ready]

[2022-07-25 Approved at July 2022 virtual plenary. Status changed: Ready → WP.]

Proposed resolution:

This wording is relative to N4910.

  1. Modify 22.8.7.4 [expected.void.assign] as indicated:

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

    -4- Effects:

    1. (4.1) — If this->has_value() && rhs.has_value() is true, no effects.

    2. (4.2) — Otherwise, if this->has_value() is true, equivalent to:

      construct_at(addressof(unex), std::move(rhs.unex));
      has_val = false;
      
    3. (4.3) — Otherwise, if rhs.has_value() is true, destroys unex and sets has_val to true.

    4. (4.4) — Otherwise, equivalent to unex = std::move(rhs.error()).