Title
Sorting a range of pairs
Status
c++23
Section
[pairs.spec]
Submitter
Barry Revzin

Created on 2023-01-28.00:00:00 last changed 5 months ago

Messages

Date: 2023-02-13.11:31:32

Proposed resolution:

This wording is relative to N4928.

  1. Modify [utility.syn], header <utility> synopsis, as indicated:

    […]
    // [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>&);
    […]
    
  2. Modify [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- […]

Date: 2023-02-13.00:00:00

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

Date: 2023-02-09.02:42:50

[ Issaquah 2023-02-07; LWG ]

Move to Immediate for C++23

Date: 2023-02-15.00:00:00

[ 2023-02-06; Reflector poll ]

Set priority to 2 after reflector poll.

Date: 2023-02-15.00:00:00

[ 2023-02-05; Barry provides wording ]

Date: 2023-01-28.00:00:00

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.

While the zip family of range adapters no longer has this problem, nothing prevents users from themselves creating a range whose reference type is 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>&.

History
Date User Action Args
2023-11-22 15:47:43adminsetstatus: wp -> c++23
2023-02-13 11:31:32adminsetmessages: + msg13395
2023-02-13 11:31:32adminsetstatus: immediate -> wp
2023-02-09 02:42:50adminsetmessages: + msg13305
2023-02-09 02:42:50adminsetstatus: new -> immediate
2023-02-06 15:13:50adminsetmessages: + msg13273
2023-02-05 19:36:14adminsetmessages: + msg13260
2023-02-05 19:36:14adminsetmessages: + msg13259
2023-01-28 00:00:00admincreate