在 C++23 中,仍然无法使用 value_type/reference 为pair的代理迭代器对范围进行排序吗?

康桓瑋*_*康桓瑋 6 c++ std-ranges c++23

尽管P2321zip提供了、 和P2165common_reference之间的专业化类对象之间的兼容性使得和可以相互转换,但 的比较函数在[pairs.spec]中只有以下候选:pairtuplepairtupletuplepairpair

template<class T1, class T2>
  constexpr common_comparison_category_t<...>
    operator<=>(const pair<T1, T2>& x, const pair<T1, T2>& y);
Run Code Online (Sandbox Code Playgroud)

注意到这里只有两个模板参数,所以我们仍然无法比较两个不同的pairs,例如

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<'
Run Code Online (Sandbox Code Playgroud)

pair这意味着使用as value_type/ 的代理迭代器reference始终无法满足这个sortable概念,即iter_value_t<I>必须与 进行比较iter_reference_t<I>,这表明ranges::sort对于此类迭代器(例如P2165zip_view::iterator之前的迭代器)不起作用,除非手动传入自定义比较器:

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>.
Run Code Online (Sandbox Code Playgroud)

为什么标准pair引入异构比较来支持使用此类迭代器对范围进行排序,即使在 C++23 中也是如此?这是故意的吗?或者我错过了什么?

Cas*_*sey 1

为什么标准不引入异构pair比较来支持使用此类迭代器对范围进行排序,即使在 C++23 中也是如此?

LWG-3865“对 s 范围进行排序pair正是这样做的。它最近在 2023-02 WG21 会议上被合并到 C++23 工作草案中。(“最近”就像“在撰写本文时更新的工作草案尚未完成”,因此如果您在最新的草案中找不到它,请不要感到惊讶。)