const
-qualified monadic overloads for std::expected
Section: 22.8.6.7 [expected.object.monadic], 22.8.7.7 [expected.void.monadic] Status: C++23 Submitter: Sy Brand Opened: 2023-02-09 Last modified: 2023-11-22
Priority: Not Prioritized
View all other issues in [expected.object.monadic].
View all issues with C++23 status.
Discussion:
The constraints for and_then
, transform
, transform_error
, and or_else
for std::expected
seem incorrect for const
overloads. E.g., from 22.8.6.7 [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>
istrue
.
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.
Modify 22.8.6.7 [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<
isEdecltype((error()))>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<
isEdecltype((error()))>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<
isTdecltype((value()))>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<
isTdecltype((value()))>true
. […]template<class F> constexpr auto transform(F&& f) &; template<class F> constexpr auto transform(F&& f) const &;[…]
-18- Constraints:is_copy_constructible_v<
isEdecltype((error()))>true
. […]template<class F> constexpr auto transform(F&& f) &&; template<class F> constexpr auto transform(F&& f) const &&;[…]
-22- Constraints:is_move_constructible_v<
isEdecltype((error()))>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<
isTdecltype((value()))>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<
isTdecltype((value()))>true
.Modify 22.8.7.7 [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<
isEdecltype((error()))>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<
isEdecltype((error()))>true
. […]template<class F> constexpr auto transform(F&& f) &; template<class F> constexpr auto transform(F&& f) const &;[…]
-16- Constraints:is_copy_constructible_v<
isEdecltype((error()))>true
. […]template<class F> constexpr auto transform(F&& f) &&; template<class F> constexpr auto transform(F&& f) const &&;[…]
-20- Constraints:is_move_constructible_v<
isEdecltype((error()))>true
. […]
[Issaquah 2023-02-09; Jonathan provides improved wording]
[Issaquah 2023-02-09; LWG]
Move to Immediate for C++23
[2023-02-13 Approved at February 2023 meeting in Issaquah. Status changed: Immediate → WP.]
Proposed resolution:
This wording is relative to N4928.
Modify 22.8.6.7 [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_
iscopy_constructible_v<E, decltype(error())>true
. […]template<class F> constexpr auto and_then(F&& f) &&; template<class F> constexpr auto and_then(F&& f) const &&;[…]
-6- Constraints:is_
iscopy_constructible_v<E, decltype(std::move(error()))>true
. […]template<class F> constexpr auto or_else(F&& f) &; template<class F> constexpr auto or_else(F&& f) const &;[…]
-10- Constraints:is_
iscopy_constructible_v<T, decltype(value())>true
. […]template<class F> constexpr auto or_else(F&& f) &&; template<class F> constexpr auto or_else(F&& f) const &&;[…]
-14- Constraints:is_
iscopy_constructible_v<T, decltype(std::move(value()))>true
. […]template<class F> constexpr auto transform(F&& f) &; template<class F> constexpr auto transform(F&& f) const &;[…]
-18- Constraints:is_
iscopy_constructible_v<E, decltype(error())>true
. […]template<class F> constexpr auto transform(F&& f) &&; template<class F> constexpr auto transform(F&& f) const &&;[…]
-22- Constraints:is_
iscopy_constructible_v<E, decltype(std::move(error()))>true
. […]template<class F> constexpr auto transform_error(F&& f) &; template<class F> constexpr auto transform_error(F&& f) const &;[…]
-26- Constraints:is_
iscopy_constructible_v<T, decltype(value())>true
. […]template<class F> constexpr auto transform_error(F&& f) &&; template<class F> constexpr auto transform_error(F&& f) const &&;[…]
-30- Constraints:is_
iscopy_constructible_v<T, decltype(std::move(value()))>true
.
Modify 22.8.7.7 [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_
iscopy_constructible_v<E, decltype(error())>true
. […]template<class F> constexpr auto and_then(F&& f) &&; template<class F> constexpr auto and_then(F&& f) const &&;[…]
-6- Constraints:is_
iscopy_constructible_v<E, decltype(std::move(error()))>true
. […]template<class F> constexpr auto transform(F&& f) &; template<class F> constexpr auto transform(F&& f) const &;[…]
-16- Constraints:is_
iscopy_constructible_v<E, decltype(error())>true
. […]template<class F> constexpr auto transform(F&& f) &&; template<class F> constexpr auto transform(F&& f) const &&;[…]
-20- Constraints:is_
iscopy_constructible_v<E, decltype(std::move(error()))>true
. […]