C++20中的Three-way comparison
mob 发布于 2022-01-17

三向比较运算符表达式的形式为

 
lhs <=> rhs    
 

The expression returns an object such that

  • (<=> b) < 0 if lhs < rhs
  • (<=> b) > 0 if lhs > rhs
  • (<=> b) == 0 if lhs and rhs are equal/equivalent.

如果其中一个运算符的类型是 bool 而另一个不是, 那么格式错误.

如果两个运算符都是 算数类型, 或者,如果一个操作数具有非范围枚举类型,而另一个操作数具有整数类型,通常的算术转换应用于操作数,然后

  • 如果需要进行窄化转换,而不是从整数类型转换为浮点类型,则程序的格式不正确。
  • 否则,如果操作数具有整数类型,则运算符将生成 std::strong_ordering:
  • std::strong_ordering::equal 如果两个操作数在算术上相等
  • std::strong_ordering::less 如果第一个操作数在算术上小于第二个操作数
  • std::strong_ordering::greater 如果第一个操作数在算术上大于第二个操作数.
  • 否则,操作数为浮点类型,运算符将生成类型为的PRV std::partial_ordering. 表达式 <=> b 产生下面
  • std::partial_ordering::less if a小于 b
  • std::partial_ordering::greater if a 大于 b
  • std::partial_ordering::equivalent if a 等于 b (-0 <=> +0 是相等的)
  • std::partial_ordering::unordered (NaN <=> anything是无序的).

如果两个操作数具有相同的枚举类型 E, 运算符生成将操作数转换为基础类型E并应用 <=> 转换操作数.

如果至少有一个操作数是指针或指向成员的指针,则数组到指针的转换, 根据需要应用派生到基指针转换、函数指针转换和限定转换,以将两个操作数转换为相同的指针类型,并且生成的指针类型是对象指针类型, <=> q 返回一个 prvalue 类型: std::strong_ordering:

  • std::strong_ordering::equal if == q,
  • std::strong_ordering::less if < q,
  • std::strong_ordering::greater if > q.
  • 如果未指定这些指针值的比较(例如,当它们未指向同一对象或数组时),则未指定结果.

否则,程序的格式就不正确。

在针对用户定义运算符的重载解析中,对于指针或枚举类型T,以下函数签名参与重载解析:

R operator<=>(T, T);
   
     

其中R是以上定义的组合类别类型。

#include <compare>
#include <iostream>
 
int main()
{
    double foo = -0.0;
    double bar = 0.0;
 
    auto res = foo <=> bar;
 
    if (res < 0)
        std::cout << "-0 is less than 0";
    else if (res > 0)
        std::cout << "-0 is greater than 0";
    else // (res == 0)
        std::cout << "-0 and 0 are equal";
}

输出

-0 and 0 are equal

 

mob
关注 私信
文章
61
关注
0
粉丝
0