Title
Incorrect constraints on const-qualified monadic overloads for std::expected
Status
c++23
Section
[expected.object.monadic][expected.void.monadic]
Submitter
Sy Brand

Created on 2023-02-09.00:00:00 last changed 5 months ago

Messages

Date: 2023-02-13.11:31:32

Proposed resolution:

This wording is relative to n4928.

  1. Modify [expected.object.monadic] as indicated:

    template<class F> constexpr auto and_then(F&& f) &;
    template<class F> constexpr auto and_then(F&& f) const &;
    

    […]

    -2- Constraints: is_copy_constructible_v<E, decltype(error())> is true.

    […]

    template<class F> constexpr auto and_then(F&& f) &&;
    template<class F> constexpr auto and_then(F&& f) const &&;
    

    […]

    -6- Constraints: is_copy_constructible_v<E, decltype(std::move(error()))> is true.

    […]

    template<class F> constexpr auto or_else(F&& f) &;
    template<class F> constexpr auto or_else(F&& f) const &;
    

    […]

    -10- Constraints: is_copy_constructible_v<T, decltype(value())> is true.

    […]

    template<class F> constexpr auto or_else(F&& f) &&;
    template<class F> constexpr auto or_else(F&& f) const &&;
    

    […]

    -14- Constraints: is_copy_constructible_v<T, decltype(std::move(value()))> is true.

    […]

    template<class F> constexpr auto transform(F&& f) &;
    template<class F> constexpr auto transform(F&& f) const &;
    

    […]

    -18- Constraints: is_copy_constructible_v<E, decltype(error())> is true.

    […]

    template<class F> constexpr auto transform(F&& f) &&;
    template<class F> constexpr auto transform(F&& f) const &&;
    

    […]

    -22- Constraints: is_copy_constructible_v<E, decltype(std::move(error()))> is true.

    […]

    template<class F> constexpr auto transform_error(F&& f) &;
    template<class F> constexpr auto transform_error(F&& f) const &;
    

    […]

    -26- Constraints: is_copy_constructible_v<T, decltype(value())> is true.

    […]

    template<class F> constexpr auto transform_error(F&& f) &&;
    template<class F> constexpr auto transform_error(F&& f) const &&;
    

    […]

    -30- Constraints: is_copy_constructible_v<T, decltype(std::move(value()))> is true.

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

    template<class F> constexpr auto and_then(F&& f) &;
    template<class F> constexpr auto and_then(F&& f) const &;
    

    […]

    -2- Constraints: is_copy_constructible_v<E, decltype(error())> is true.

    […]

    template<class F> constexpr auto and_then(F&& f) &&;
    template<class F> constexpr auto and_then(F&& f) const &&;
    

    […]

    -6- Constraints: is_copy_constructible_v<E, decltype(std::move(error()))> is true.

    […]

    template<class F> constexpr auto transform(F&& f) &;
    template<class F> constexpr auto transform(F&& f) const &;
    

    […]

    -16- Constraints: is_copy_constructible_v<E, decltype(error())> is true.

    […]

    template<class F> constexpr auto transform(F&& f) &&;
    template<class F> constexpr auto transform(F&& f) const &&;
    

    […]

    -20- Constraints: is_copy_constructible_v<E, decltype(std::move(error()))> is true.

    […]

Date: 2023-02-13.00:00:00

[ 2023-02-13 Approved at February 2023 meeting in Issaquah. Status changed: Immediate → WP. ]

Date: 2023-02-10.00:55:24

[ Issaquah 2023-02-09; LWG ]

Move to Immediate for C++23

Date: 2023-02-10.00:55:24

[ Issaquah 2023-02-09; Jonathan provides improved wording ]

Date: 2023-02-10.00:21:48

The constraints for and_then, transform, transform_error, and or_else for std::expected seem incorrect for const overloads. E.g., from [expected.object.monadic]

template<class F> constexpr auto transform(F&& f) &&;
template<class F> constexpr auto transform(F&& f) const &&;
[…]

Constraints: is_move_constructible_v<E> is true.

That constraint should likely be is_move_constructible_v<const E> for the const-qualified version. Same for the lvalue overloads, and for the three other functions, including in the void partial specialization. For example, currently this code would result in a hard compiler error inside the body of transform rather than failing the constraint:

const std::expected<int, std::unique_ptr<int>> e;
std::move(e).transform([](auto) { return 42; });

Previous resolution [SUPERSEDED]:

This wording is relative to n4928.

  1. Modify [expected.object.monadic] as indicated:

    template<class F> constexpr auto and_then(F&& f) &;
    template<class F> constexpr auto and_then(F&& f) const &;
    

    […]

    -2- Constraints: is_copy_constructible_v<Edecltype((error()))> is true.

    […]

    template<class F> constexpr auto and_then(F&& f) &&;
    template<class F> constexpr auto and_then(F&& f) const &&;
    

    […]

    -6- Constraints: is_move_constructible_v<Edecltype((error()))> is true.

    […]

    template<class F> constexpr auto or_else(F&& f) &;
    template<class F> constexpr auto or_else(F&& f) const &;
    

    […]

    -10- Constraints: is_copy_constructible_v<Tdecltype((value()))> is true.

    […]

    template<class F> constexpr auto or_else(F&& f) &&;
    template<class F> constexpr auto or_else(F&& f) const &&;
    

    […]

    -14- Constraints: is_move_constructible_v<Tdecltype((value()))> is true.

    […]

    template<class F> constexpr auto transform(F&& f) &;
    template<class F> constexpr auto transform(F&& f) const &;
    

    […]

    -18- Constraints: is_copy_constructible_v<Edecltype((error()))> is true.

    […]

    template<class F> constexpr auto transform(F&& f) &&;
    template<class F> constexpr auto transform(F&& f) const &&;
    

    […]

    -22- Constraints: is_move_constructible_v<Edecltype((error()))> is true.

    […]

    template<class F> constexpr auto transform_error(F&& f) &;
    template<class F> constexpr auto transform_error(F&& f) const &;
    

    […]

    -26- Constraints: is_copy_constructible_v<Tdecltype((value()))> is true.

    […]

    template<class F> constexpr auto transform_error(F&& f) &&;
    template<class F> constexpr auto transform_error(F&& f) const &&;
    

    […]

    -30- Constraints: is_move_constructible_v<Tdecltype((value()))> is true.

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

    template<class F> constexpr auto and_then(F&& f) &;
    template<class F> constexpr auto and_then(F&& f) const &;
    

    […]

    -2- Constraints: is_copy_constructible_v<Edecltype((error()))> is true.

    […]

    template<class F> constexpr auto and_then(F&& f) &&;
    template<class F> constexpr auto and_then(F&& f) const &&;
    

    […]

    -6- Constraints: is_move_constructible_v<Edecltype((error()))> is true.

    […]

    template<class F> constexpr auto transform(F&& f) &;
    template<class F> constexpr auto transform(F&& f) const &;
    

    […]

    -16- Constraints: is_copy_constructible_v<Edecltype((error()))> is true.

    […]

    template<class F> constexpr auto transform(F&& f) &&;
    template<class F> constexpr auto transform(F&& f) const &&;
    

    […]

    -20- Constraints: is_move_constructible_v<Edecltype((error()))> is true.

    […]

History
Date User Action Args
2023-11-22 15:47:43adminsetstatus: wp -> c++23
2023-02-13 11:31:32adminsetmessages: + msg13402
2023-02-13 11:31:32adminsetstatus: immediate -> wp
2023-02-10 00:55:24adminsetmessages: + msg13325
2023-02-10 00:55:24adminsetstatus: new -> immediate
2023-02-10 00:21:48adminsetmessages: + msg13322
2023-02-09 19:08:45adminsetmessages: + msg13318
2023-02-09 00:00:00admincreate