为什么ranges v3库的sort不识别自定义类型operator<而std::sort可以?
编译错误原因分析
这个问题的核心是std::sort和range-v3的ranges::sort对默认比较运算符的查找规则存在差异,具体原因如下:
std::sort的默认比较逻辑直接使用<运算符做非限定名称查找,除了参数依赖查找(ADL)外,还会匹配当前作用域可见的全局运算符重载,因此你定义在全局的bool operator<(A const&, A const&)可以被正常找到,代码编译通过。ranges::sort默认使用ranges::less作为比较器,它对<运算符的查找遵循范围库的定制点规则:仅通过参数依赖查找匹配类型关联命名空间内的运算符重载,你定义的全局独立operator<不属于struct A的关联命名空间内的可见重载,因此无法被ranges::less识别,不满足sortable概念的要求,触发SFINAE导致候选函数被排除,最终报无匹配函数的编译错误。
修复方案
你可以选择任意一种方式修复该问题:
- 将
operator<定义为struct A的内部友元函数,使其属于类型关联命名空间的可见重载:
struct A { int x; A(int x) : x{x} {} friend bool operator<(A const& a1, A const& a2) { return a1.x < a2.x; } };
- 调用
ranges::sort时显式传入自定义比较器,绕过ranges::less的查找规则:
ranges::sort(v, [](A const& a1, A const& a2) { return a1 < a2; });
内容的提问来源于stack exchange,提问作者Enlico
相关产品推荐
相关产品推荐

