Although P2321 zip
provides the common_reference
specialization for pair
, and P2165 Compatibility between tuple
, pair
and tuple
-like objects makes tuple
and pair
interconvertible, the comparison function of pair
only has the following candidates in [pairs.spec]:
template<class T1, class T2>
constexpr common_comparison_category_t<...>
operator<=>(const pair<T1, T2>& x, const pair<T1, T2>& y);
Noted that there are only two template parameters here, so we still cannot compare two different pair
s, for example:
using value_type = pair<int , string >;
using reference = pair<int&, string&>;
value_type val = {1, "a"};
reference ref = val;
val < ref; // no match for 'operator<'
This means that a proxy iterator using a pair
as value_type
/reference
always failed to satisfy the sortable
concept, that is, iter_value_t<I>
must be comparable with iter_reference_t<I>
, which indicates that ranges::sort
won't work for such a class of iterators (such as zip_view::iterator
before P2165) unless manually pass in a custom comparator:
std::vector<int> x, y;
ranges::sort(std::views::zip(x, y)); // This won't work before P2165
// because the reference type of zip_view is pair<int&, int&>,
// which cannot be compared with its value type pair<int, int>.
// After P2165 its reference type was changed to tuple<int&, int&>,
// which works because it can be compared with its value type tuple<int, int>.
Why doesn't the standard introduce heterogeneous pair
comparisons to support sorting a range with such kinds of iterators even in C++23? Is this intentional? Or am I missing something?