std::expected<T,E>::value() & assumes E is copy constructible
Jonathan Wakely

Created on 2022-12-20.00:00:00 last changed 8 months ago


Date: 2023-02-13.11:31:32

Proposed resolution:

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

    constexpr const T& value() const &;
    constexpr T& value() &;

    -?- Mandates: is_copy_constructible_v<E> is true.

    -8- Returns: val, if has_value() is true.

    -9- Throws: bad_expected_access(as_const(error())) if has_value() is false.

    constexpr T&& value() &&;
    constexpr const T&& value() const &&;

    -?- Mandates: is_copy_constructible_v<E> is true and is_constructible_v<E, decltype(std::move(error()))> is true.

    -10- Returns: std::move(val), if has_value() is true.

    -11- Throws: bad_expected_access(std::move(error())) if has_value() is false.

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:47:00

[ Issaquah 2023-02-09; LWG ]

Move to Immediate for C++23

Date: 2023-02-09.09:42:20

[expected.object.obs] p9 says:

Throws: bad_expected_access(error()) if has_value() is false.

But if error() returns a reference to a move-only type then it can't be copied and the function body is ill-formed. Should it be constrained with is_copy_constructible_v<E>? Or just mandate it?

Similarly, the value()&& and value() const&& overloads require is_move_constructible_v<E> to be true for bad_expected_access(std::move(error())) to be valid. Casey Carter pointed out they also require it to be copyable so that the exception can be thrown, as per [except.throw] p5.

Date User Action Args
2023-11-22 15:47:43adminsetstatus: wp -> c++23
2023-02-13 11:31:32adminsetmessages: + msg13392
2023-02-13 11:31:32adminsetstatus: immediate -> wp
2023-02-10 00:47:00adminsetmessages: + msg13324
2023-02-10 00:47:00adminsetstatus: new -> immediate
2022-12-20 12:34:38adminsetmessages: + msg13164
2022-12-20 00:00:00admincreate