You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++23中仍无法对以pair为值/引用类型的代理迭代器范围排序?

关于C++23中pair异构比较缺失的疑问

尽管P2321为zip给pair提供了common_reference特化,且P2165《tuple、pair与类tuple对象的兼容性》实现了tuple与pair的互转,但在[pairs.spec]中,pair的比较函数仅提供同构版本:

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

该版本仅支持模板参数完全一致的pair比较,因此无法比较不同类型的pair,例如:

using value_type = pair<int , string >;
using reference  = pair<int&, string&>;

value_type val = {1, "a"};
reference  ref = val;
val < ref; // 无匹配的'operator<'

这直接导致以pair作为value_type/reference的代理迭代器无法满足sortable概念——该概念要求iter_value_t<I>必须能与iter_reference_t<I>比较,进而使得ranges::sort无法作用于这类迭代器(比如P2165之前的zip_view::iterator),除非手动传入自定义比较器:

std::vector<int> x, y;
ranges::sort(std::views::zip(x, y)); // P2165之前无法正常工作
// 因为zip_view的引用类型是pair<int&, int&>,无法与其值类型pair<int, int>比较

// P2165之后引用类型改为tuple<int&, int&>,就能正常工作
// 因为tuple支持与对应值类型的比较

为什么C++23未引入pair的异构比较?

这并非疏漏,而是标准委员会有意的设计选择,核心考量如下:

  1. 历史兼容性与歧义规避
    异构比较的引入可能引发重载决议歧义。当存在隐式转换路径时,同构与异构比较的候选函数可能让编译器无法确定最佳匹配,破坏既有代码的稳定行为。

  2. 已有替代方案tuple
    P2165已将zip_view的引用类型从pair改为tuple,而tuple本身支持异构比较(通过分别推导左右操作数的模板参数),足以满足代理迭代器的sortable需求。标准委员会认为,既然已有更通用的tuple作为解决方案,专门为pair添加异构比较的优先级较低。

  3. 控制pair的设计复杂度
    pair的设计目标是轻量化、接口简洁的二元组结构,引入异构比较会增加其接口复杂度。这类跨类型比较需求,完全可以通过tuple转换或自定义比较器实现,无需修改pair的核心接口。

  4. 标准演进的优先级分配
    C++23的核心特性集中在范围库完善、协程、模块化等方向,pair的异构比较不属于迫切需要解决的问题,因此未被纳入版本计划。

如果确实需要比较不同类型的pair,除了手动传入自定义比较器外,也可以将pair转换为tuple后利用其异构比较能力:

val < static_cast<tuple<int, string>>(ref); // 可行

内容的提问来源于stack exchange,提问作者康桓瑋

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.02 19:10:19