三路比较运算符<=>
¶
- 作用:三路比较可以看做
== 、 != 、 < 、 <= 、 > 、 >=
的集合,实现一个三路比较运算符可以替代其它六个比较运算
1 三路比较的使用¶
- 三路比较返回值有三种
- partial_ordering
- strong_ordering
- weak_ordering
- 三路比较结果只能与 0、NULL 和 nullptr 做比较
- 示例
#include<compare>
int main(){
auto comp=1 <=> 2;
comp<NULL;
comp<0;
comp<nullptr;
}
2 重写三路比较运算符¶
在类中,可以指示编译器默认生成,也可以由用户定义
2.1 默认三路比较¶
要使用默认的三路比较,只需要假设 =default
,编译器会安装类成员出现顺序依次去做三路比较
#include<compare>
class Point {
int y;
int x;
public:
Point() :x(0), y(0) {}
Point(int x,int y):x(x),y(y){}
auto operator<=>(const Point&) const = default;
};
因此类中成员顺序会影响到最终比较结果
#include <iostream>
#include<compare>
#include<set>
class Point1 {
int y;
int x;
public:
Point() :x(0), y(0) {}
Point(int x,int y):x(x),y(y){}
auto operator<=>(const Point&) const = default;
};
class Point2 {
int x;
int y;
public:
Point() :x(0), y(0) {}
Point(int x,int y):x(x),y(y){}
auto operator<=>(const Point&) const = default;
};
int main() {
Point1 pt1(1,2), pt2(2,1);
//因为y在x前声明,首先比较y,pt1.y>pt2.y,所以是false
if (pt1 < pt2)
{
std::cout << "true";
}
else {
std::cout << "false" << std::endl;
}
Point2 pt3(1,2), pt4(2,1);
//因为x在y前声明,首先比较x,pt3.x<pt4.x,所以是true
if (pt3 < pt4)
{
std::cout << "true";
}
else {
std::cout << "false" << std::endl;
}
}
2.2 自定义三路比较¶
自定义三路比较需要遍历所有成员,且父类也需要比较
class TotallyOrdered : Base {
string tax_id;
string first_name;
string last_name;
public:
std::strong_ordering operator<=>(const TotallyOrdered& that) const {
if (auto cmp = (Base&)(*this) <=> (Base&)that; cmp != 0) return cmp;
if (auto cmp = last_name <=> that.last_name; cmp != 0) return cmp;
if (auto cmp = first_name <=> that.first_name; cmp != 0) return cmp;
return tax_id <=> that.tax_id;
}
// ... non-comparison functions ...
};