C++比较对象的重载解析

huangapple go评论59阅读模式
英文:

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 &lt;typename L, typename R&gt;
bool operator &gt; (const L&amp; l, const R&amp; r) { return r &lt; l; }

(operator &lt; is usually a member)

When I now try and use operator &lt;=&gt; 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 == 0a <=> b < 0,可用于将三向比较运算符的结果转换为布尔关系;请参见std::is_eqstd::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 &lt;=&gt; b == 0 or a &lt;=&gt; b &lt; 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 &gt; comparable to anything else. Either remove it, or add a requires clause.

template &lt;typename L, typename R&gt;
requires requires (const L&amp; l, const R&amp; r) { r &lt; l; }
bool operator &gt; (const L&amp; l, const R&amp; r) { return r &lt; l; }

huangapple
  • 本文由 发表于 2023年2月8日 18:53:43
  • 转载请务必保留本文链接:https://go.coder-hub.com/75384738.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定