Created on 2021-06-07.00:00:00 last changed 13 months ago
Proposed resolution:
This wording is relative to N4885.
Modify [optional.syn], header <optional> synopsis, as indicated:
[…] // [optional.optional], class template optional template<class T> class optional; template<class T> constexpr bool is-optional = false; // exposition only template<class T> constexpr bool is-optional<optional<T>> = true; // exposition only […] // [optional.comp.with.t], comparison with T […] template<class T, class U> constexpr bool operator>=(const optional<T>&, const U&); template<class T, class U> constexpr bool operator>=(const T&, const optional<U>&); template<class T,three_way_comparable_with<T>class U> requires (!is-optional<U>) && three_way_comparable_with<T, U> constexpr compare_three_way_result_t<T, U> operator<=>(const optional<T>&, const U&); […]
Modify [optional.comp.with.t] as indicated:
template<class T,three_way_comparable_with<T>class U> requires (!is-optional<U>) && three_way_comparable_with<T, U> constexpr compare_three_way_result_t<T, U> operator<=>(const optional<T>& x, const U& v);-25- Effects: Equivalent to: return bool(x) ? *x <=> v : strong_ordering::less;
[ 2021-10-14 Approved at October 2021 virtual plenary. Status changed: Voting → WP. ]
[ 2021-06-23; Reflector poll ]
Set status to Tentatively Ready after five votes in favour during reflector poll.
[ 2021-06-14; Improved proposed wording based on reflector discussion ]
The three-way-comparison operator for optionals and non-optionals is defined in [optional.comp.with.t] paragraph 25:
template<class T, three_way_comparable_with<T> U> constexpr compare_three_way_result_t<T, U> operator<=>(const optional<T>& x, const U& v);-25- Effects: Equivalent to: return bool(x) ? *x <=> v : strong_ordering::less;
Checking three_way_comparable_with in particular requires checking that x < v is well-formed for an lvalue const optional<T> and lvalue const U. x < v can be rewritten as (v <=> x) > 0. If U is a specialization of optional, this overload could be used for v <=> x, but first we must check the constraints…
The straightforward fix for this recursion seems to be to refuse to check three_way_comparable_with<T> when U is a specialization of optional. MSVC has been shipping such a fix; our initial tests for this new operator triggered the recursion.
Previous resolution [SUPERSEDED]:
This wording is relative to N4885.
Modify [optional.syn], header <optional> synopsis, as indicated:
[…] // [optional.comp.with.t], comparison with T […] template<class T, class U> constexpr bool operator>=(const optional<T>&, const U&); template<class T, class U> constexpr bool operator>=(const T&, const optional<U>&); template<class T,three_way_comparable_with<T>class U> requires see below constexpr compare_three_way_result_t<T, U> operator<=>(const optional<T>&, const U&); […]Modify [optional.comp.with.t] as indicated:
template<class T,three_way_comparable_with<T>class U> requires (!is-specialization-of<U, optional>) && three_way_comparable_with<T, U> constexpr compare_three_way_result_t<T, U> operator<=>(const optional<T>&, const U&);-?- The exposition-only trait template is-specialization-of<A, B> is a constant expression with value true when A denotes a specialization of the class template B, and false otherwise.
-25- Effects: Equivalent to: return bool(x) ? *x <=> v : strong_ordering::less;
History | |||
---|---|---|---|
Date | User | Action | Args |
2023-11-22 15:47:43 | admin | set | status: wp -> c++23 |
2021-10-14 09:56:08 | admin | set | messages: + msg12129 |
2021-10-14 09:56:08 | admin | set | status: voting -> wp |
2021-09-29 12:57:28 | admin | set | status: ready -> voting |
2021-06-23 14:16:45 | admin | set | messages: + msg11962 |
2021-06-23 14:16:45 | admin | set | status: new -> ready |
2021-06-14 19:04:56 | admin | set | messages: + msg11934 |
2021-06-12 12:53:03 | admin | set | messages: + msg11920 |
2021-06-07 00:00:00 | admin | create |