Title
Bad Mandates for expected::transform_error overloads
Status
c++23
Section
[expected.object.monadic][expected.void.monadic]
Submitter
Casey Carter

Created on 2023-01-29.00:00:00 last changed 13 months ago

Messages

Date: 2023-02-13.10:17:57

Proposed resolution:

This wording is relative to N4928.

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

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

    […]

    -27- Mandates: G is a valid value type for expectedtemplate argument for unexpected ([expected.un.general]) and the declaration

    G g(invoke(std::forward<F>(f), error()));
    

    is well-formed.

    […]

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

    […]

    -31- Mandates: G is a valid value type for expectedtemplate argument for unexpected ([expected.un.general]) and the declaration

    G g(invoke(std::forward<F>(f), std::move(error())));
    

    is well-formed.

    […]

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

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

    […]

    -24- Mandates: G is a valid value type for expectedtemplate argument for unexpected ([expected.un.general]) and the declaration

    G g(invoke(std::forward<F>(f), error()));
    

    is well-formed.

    […]

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

    […]

    -27- Mandates: G is a valid value type for expectedtemplate argument for unexpected ([expected.un.general]) and the declaration

    G g(invoke(std::forward<F>(f), std::move(error())));
    

    is well-formed.

    […]

Date: 2023-02-13.00:00:00

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

Date: 2023-02-15.00:00:00

[ 2023-02-06; Reflector poll ]

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

Date: 2023-01-29.12:38:36

The overloads of expected::transform_error mandate that "[type] G is a valid value type for expected" ([expected.object.monadic]/27 and 31 as well as [expected.void.monadic]/24 and 27)).

All of these overloads then instantiate expected<T, G> (for some type T) which doesn't require G to be a valid value type for expected ([expected.object.general]/2) but instead requires that G is "a valid template argument for unexpected" ([expected.object.general]/2). Comparing [expected.object.general]/2 with [expected.un.general]/2 it's clear that there are types — const int, for example — which are valid value types for expected but not valid template arguments for unexpected. Presumably this unimplementable requirement is a typo, and the subject paragraphs intended to require that G be a valid template argument for unexpected.

History
Date User Action Args
2023-11-22 15:47:43adminsetstatus: wp -> c++23
2023-02-13 10:17:57adminsetmessages: + msg13375
2023-02-13 10:17:57adminsetstatus: voting -> wp
2023-02-06 15:33:48adminsetstatus: ready -> voting
2023-02-06 15:13:50adminsetmessages: + msg13267
2023-02-06 15:13:50adminsetstatus: new -> ready
2023-01-29 12:06:09adminsetmessages: + msg13231
2023-01-29 00:00:00admincreate