英文:
Overload Resolution for comparisons of c++ compare objects
问题
我想在我们的代码库中介绍宇宙飞船运算符,但我们目前正在使用全局模板比较运算符,类似于这样:
template <typename L, typename R>
bool operator > (const L& l, const R& r) { return r < l; }
(通常 operator <
是一个成员函数)
当我现在尝试在一个类中使用 operator <=>
时,我的模板运算符被选择了!为什么?
在cpp参考中,ordering operators
的示例实现是友元函数,在任何情况下都应优于模板函数。
示例链接:https://godbolt.org/z/r8qjK6q6f
英文:
I wanted to introduce the spaceship operator in our Code Base, but we are currently using global templated comparison operators like this:
template <typename L, typename R>
bool operator > (const L& l, const R& r) { return r < l; }
(operator <
is usually a member)
When I now try and use operator <=>
in a class, my templated operator gets chosen! Why?
In cpp reference the example implementation of the ordering operators
are friends and should in every case be superior to a templated function.
Example: https://godbolt.org/z/r8qjK6q6f
答案1
得分: 2
std::strong_ordering
具有比较运算符,其中一个参数的类型未指定。不清楚它们如何影响重载决策,尽管很可能它们故意被设计为最不可行的函数。
比较运算符在此类型的值和文字
0
之间定义。这支持表达式a <=> b == 0
或a <=> b < 0
,可用于将三向比较运算符的结果转换为布尔关系;请参见std::is_eq
、std::is_lt
等。这些函数对于普通未限定或限定查找是不可见的,只有在
std::strong_ordering
是参数的相关类时,可以通过参数相关查找找到。尝试将
std::strong_ordering
与除整数文字0
之外的任何东西进行比较的程序行为是未定义的。
您的比较模板太过通用。它暗示了任何东西都可以与任何其他东西进行>
比较。要么删除它,要么添加一个requires
子句。
template <typename L, typename R>
requires requires (const L& l, const R& r) { r < l; }
bool operator > (const L& l, const R& r) { return r < l; }
英文:
std::strong_ordering
has comparison operators for which one parameter is of unspecified type. It's not clear how they factor in overload resolution, although it is quite probable that they are intentionally the least viable function.
> Comparison operators are defined between values of this type and literal 0
. This supports the expressions a <=> b == 0
or a <=> b < 0
that can be used to convert the result of a three-way comparison operator to a boolean relationship; see std::is_eq
, std::is_lt
, etc.
>
> These functions are not visible to ordinary unqualified or qualified lookup, and can only be found by argument-dependent lookup when std::strong_ordering
is an associated class of the arguments.
>
> The behavior of a program that attempts to compare a strong_ordering with anything other than the integer literal 0
is undefined.
Your comparison template is wildly too general. It is implying that anything is >
comparable to anything else. Either remove it, or add a requires clause.
template <typename L, typename R>
requires requires (const L& l, const R& r) { r < l; }
bool operator > (const L& l, const R& r) { return r < l; }
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论