pair
sSection: 22.3.3 [pairs.spec] Status: C++23 Submitter: Barry Revzin Opened: 2023-01-28 Last modified: 2023-11-22
Priority: 2
View all other issues in [pairs.spec].
View all issues with C++23 status.
Discussion:
Consider this example:
#include <algorithm> #include <ranges> int main() { int a[3] = {1, 2, -1}; int b[3] = {1, 4, 1}; std::ranges::sort(std::views::zip(a, b)); }
This is currently valid C++23 code, but wasn't before P2165 (Compatibility between tuple
, pair
and tuple-like objects). Before P2165, zip(a, b)
returned a range whose reference was
std::pair<int&, int&>
and whose value_type
was std::pair<int, int>
and
std::pair
, unlike std::tuple
, does not have any heterogeneous comparisons — which is required to
satisfy the sortable
concept.
pair<T&, U&>
and whose value_type
is pair<T, U>
(which is now a valid range after the zip paper) and then discovering that this range isn't sortable, even though the
equivalent using tuple
is.
Suggested resolution:
Change pair
's comparison operators from comparing two arguments of type const pair<T1, T2>&
to instead comparing arguments of types const pair<T1, T2>&
and const pair<U1, U2>&
.
[2023-02-05; Barry provides wording]
[2023-02-06; Reflector poll]
Set priority to 2 after reflector poll.
[Issaquah 2023-02-07; 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.2.1 [utility.syn], header <utility>
synopsis, as indicated:
[…] // 22.3.3 [pairs.spec], pair specialized algorithms template<class T1, class T2, class U1, class U2> constexpr bool operator==(const pair<T1, T2>&, const pair<TU1,TU2>&); template<class T1, class T2, class U1, class U2> constexpr common_comparison_category_t<synth-three-way-result<T1, U1>, synth-three-way-result<T2, U2>> operator<=>(const pair<T1, T2>&, const pair<TU1,TU2>&); […]
Modify 22.3.3 [pairs.spec] as indicated:
template<class T1, class T2, class U1, class U2> constexpr bool operator==(const pair<T1, T2>& x, const pair<TU1,TU2>& y);-1- […]
-2- […]template<class T1, class T2, class U1, class U2> constexpr common_comparison_category_t<synth-three-way-result<T1, U1>, synth-three-way-result<T2, U2>> operator<=>(const pair<T1, T2>& x, const pair<TU1,TU2>& y);-3- […]