C++20 三路比较运算符

三路比较运算符

简单使用

基本数据类型已经已经内置定义了三路比较运算符,示例如下。

#include <iostream>

using namespace std;

int main()
{
	double var1 = 1.0;
	double var2 = 2.0;
	auto res = var1 <=> var2;
	if(res < 0)
		cout << "<" << endl;
	else if(res > 0)
		cout << ">" << endl;
	else
		cout << "==" << endl;
	return 0;
}

三路比较运算表达式为值1 <=> 值2,可以简单的理解为当表达式为小于关系时,表达式返回负值,大于时返回正值,相等则为0。

三路比较运算的返回值。

具体内容可参考cppreference

如果操作数之一为 bool 类型而另一个不是,程序非良构。

若两个操作数均具有算术类型,或若一个具有无作用域枚举类型而另一个具有整型类型,则对各操作数应用一般算术转换,然后

若需要进行除了从整型类型到浮点类型之外的窄化转换,则程序非良构。 否则,若各操作数均具有整型类型,则运算符产出
std::strong_ordering 类型的纯右值: 若两个操作数算术上相等则为
std::strong_ordering::equal, 若第一操作数算术上小于第二个则为
std::strong_ordering::less 否则为 std::strong_ordering::greater。
否则,操作数均具有浮点类型,而运算符产出 std::partial_ordering 类型的纯右值。表达式 a <=> b 产出 若 a
小于 b 则为 std::partial_ordering::less, 若 a 大于 b 则为
std::partial_ordering::greater, 若 a 等价于 b 则为
std::partial_ordering::equivalent(-0 <=> +0 为等价), 否则为
std::partial_ordering::unordered(NaN <=> 任何值 为无序)。 若两个操作数都具有相同的枚举类型
E,则运算符产出将各操作数转换为 E 的底层类型再对转换后的操作数应用 <=> 的结果。

若至少一个操作数为指针或成员指针,则按需应用数组到指针转换、派生类到基类指针转换、函数指针转换和限定性转换,以将它们转换为同一指针类型,且结果指针类型为对象指针类型,则
p <=> q 返回 std::strong_ordering 类型的纯右值:

若 p == q 则为 std::strong_ordering::equal 若 q > p 则为
std::strong_ordering::less 若 p > q 则为 std::strong_ordering::greater。
若未指明这些指针值的比较(例如它们不指向同一对象或数组之中时),则为未指明的结果。 否则程序非良构。

以上内容来自"cppreference"

自定义类型使用三路比较运算符

一般的,可以使用编译器默认实现的三路比较运算符,示例如下。

#include <iostream>

using namespace std;

struct TestClass
{
	int var1;
	double var2;
	auto operator<=>(const TestClass&) const = default;
};

int main()
{
	TestClass c1{ 2, 3.0 };
	TestClass c2{ 3, 2.0 };
	auto res = c1 <=> c2;
	if (res < 0)
		cout << "<" << endl;
	else if (res > 0)
		cout << ">" << endl;
	else if (res == 0)
		cout << "==" << endl;
	else
		cout << "<>" << endl;
	return 0;
}

如果不使用默认实现,则可以手写其实现,示例如下。

#include <iostream>
#include <compare>

using namespace std;

struct TestClass
{
	int var1;
	double var2;
	auto operator<=>(const TestClass& other) const
	{
		if (other.var1 == var1 && other.var2 == var2)
			return std::partial_ordering::equivalent;
		if (other.var1 == var1 && other.var2 > var2 ||
			other.var1 > var1 && other.var2 == var2 ||
			other.var1 > var1 && other.var2 > var2)
			return std::partial_ordering::less;
		if (other.var1 == var1 && other.var2 < var2 ||
			other.var1 < var1 && other.var2 == var2 ||
			other.var1 < var1 && other.var2 < var2)
			return std::partial_ordering::greater;
		return std::partial_ordering::unordered;
	}
};

int main()
{
	TestClass c1{ 2, 3.0 };
	TestClass c2{ 3, 2.0 };
	auto res = c1 <=> c2;
	if (res < 0)
		cout << "<" << endl;
	else if (res > 0)
		cout << ">" << endl;
	else if (res == 0)
		cout << "==" << endl;
	else
		cout << "<>" << endl;
	return 0;
}

由上述两份代码的运行结果可以看出,自动生成的三路比较与我们自己手写的运行结果不一样,所以使用时需要注意,必须深刻理解默认生成的规则。

自动生成关系运算符

当定义了三路比较运算符后,也就相当于定义了其它比较运算符,例如operator ==是当三路比较运算返回std::partial_ordering::equivalent是为true其余情况为false,示例如下。

#include <iostream>

using namespace std;

struct TestClass
{
	int var1;
	double var2;
	auto operator<=>(const TestClass& other) const = default;
};

int main()
{
	TestClass c1{ 2, 2.0 };
	TestClass c2{ 2, 2.0 };
	if (c1 == c2)
		cout << "==" << endl;
	if (c1 < c2)
		cout << "<" << endl;
	if (c1 > c2)
		cout << ">" << endl;
	return 0;
}

上述代码将会输出‘==’。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值