C++20中头文件compare的使用
<compare>是C++20中新增加的头文件,此头文件是language support库的一部分。它包括:concepts、classes、customization point objects、functions。
1.concepts:三向比较运算符<=>,目的是简化比对对象的过程,支持所有六种关系运算符(==、!=、>、>=、<、<=),返回表示比较结果的枚举值,这个枚举值可以被用来决定两个对象是否相等、小于或大于另一个对象,详细介绍参考:https://blog.csdn.net/fengbingchun/article/details/140078283 ,测试代码如下:所有std::cout都会输出
namespace {
auto compare = []<typename T>(const T & x, const T & y) {
return x <=> y;
};
struct Point {
int x, y;
auto operator<=>(const Point& other) const = default;
};
const std::string str1{ "abc" }, str2{ "Abc" }, str3{ "abc" };
template<class Ord>
void print_cmp_type()
{
if constexpr (std::is_same_v<Ord, std::strong_ordering>)
std::cout << "strong ordering\n";
else if constexpr (std::is_same_v<Ord, std::weak_ordering>)
std::cout << "weak ordering\n";
else if constexpr (std::is_same_v<Ord, std::partial_ordering>)
std::cout << "partial ordering\n";
else
std::cout << "illegal comparison result type\n";
}
} // namespace
int test_compare_concepts()
{
constexpr auto x{ 1 }, y{ 2 }, z{ 1 };
if (compare(x, y) < 0) std::cout << x << " < " << y << std::endl;
if (compare(y, x) > 0) std::cout << y << " > " << x << std::endl;
if (compare(x, z) == 0) std::cout << x << " == " << z << std::endl;
if (compare(str2, str1) < 0) std::cout << str2 << " < " << str1 << std::endl;
if (compare(str1, str2) > 0) std::cout << str1 << " > " << str2 << std::endl;
if (compare(str1, str3) == 0) std::cout << str1 << " == " << str3 << std::endl;
return 0;
}
2.classes:
三向比较的结果类型:枚举值,支持所有六种关系运算符(==, !=, <, <=, >, >=)
类std::strong_ordering:有4种有效值:less、equal、equivalent、greater。
类std::weak_ordering:有3种有效值:less、equivalent、greater。
类std::partial_ordering:有4种有效值:less、equivalent、greater、unordered。
std::compare_three_way:执行三向比较,一般不直接调用。
std::compare_three_way_result:三向比较运算符的结果类型。
int test_compare_classes()
{
if (compare(str2, str1) == std::strong_ordering::less) std::cout << str2 << " < " << str1 << std::endl;
if (compare(str1, str2) == std::strong_ordering::greater) std::cout << str1 << " > " << str2 << std::endl;
if (compare(str1, str3) == std::strong_ordering::equal) std::cout << str1 << " == " << str3 << std::endl;
constexpr float x{ 1.f }, y{ 2.f }, z{ 1.f };
if (compare(x, y) == std::weak_ordering::less) std::cout << x << " < " << y << std::endl;
if (compare(y, x) == std::weak_ordering::greater) std::cout << y << " > " << x << std::endl;
if (compare(x, z) == std::weak_ordering::equivalent) std::cout << x << " == " << z << std::endl;
constexpr Point p1{ 1,2 }, p2{ 2,3 };
auto ret = p1 <=> p2;
if (ret == std::partial_ordering::less) std::cout << "p1 < p2" << std::endl;
if (std::compare_three_way{}(p1, p2) == std::strong_ordering::less) std::cout << "p1 < p2" << std::endl;
print_cmp_type<std::compare_three_way_result_t<int>>(); // strong ordering
print_cmp_type<std::compare_three_way_result_t<double>>(); // partial ordering
return 0;
}
执行结果如下图所示:
3.customization point objects:
std::strong_order:执行三向比较并生成std::strong_ordering类型的结果。
std::weak_order:执行三向比较并生成std::weak_ordering类型的结果。
std::partial_order:执行三向比较并生成std::partial_ordering类型的结果。
std::compare_strong_order_fallback:执行三向比较并生成std::strong_ordering类型的结果,即使运算符<=>不可用。
std::compare_weak_order_fallback:执行三向比较并生成std::weak_ordering类型的结果,即使运算符<=>不可用。
std::compare_partial_order_fallback:执行三向比较并生成std::partial_ordering类型的结果,即使运算符<=>不可用。
测试代码如下,所有std::cout都会输出
int test_compare_customization_point_objects()
{
if (std::strong_order(str1, str2) == std::strong_ordering::greater) std::cout << str1 << " > " << str2 << std::endl;
if (std::weak_order(str2, str1) == std::weak_ordering::less) std::cout << str2 << " < " << str1 << std::endl;
if (std::partial_order(str1, str3) == std::partial_ordering::equivalent) std::cout << str1 << " == " << str3 << std::endl;
if (std::compare_strong_order_fallback(str1, str2) == std::strong_ordering::greater) std::cout << str1 << " > " << str2 << std::endl;
if (std::compare_weak_order_fallback(str2, str1) == std::weak_ordering::less) std::cout << str2 << " < " << str1 << std::endl;
if (std::compare_partial_order_fallback(str1, str3) == std::partial_ordering::equivalent) std::cout << str1 << " == " << str3 << std::endl;
return 0;
}
4.functions:std::is_eq、std::is_neq、std::is_lt、std::is_lteq、std::is_gt、std::is_gteq,比较函数,这些函数将三向比较的结果转换为六个关系运算符之一的结果,依次为==、!=、<、<=、>、>=。
测试代码如下,所有std::cout都会输出
int test_compare_functions()
{
if (std::is_eq(std::strong_order(str1, str3))) std::cout << str1 << " == " << str3 << std::endl;
if (std::is_neq(std::strong_order(str1, str2))) std::cout << str1 << " != " << str2 << std::endl;
if (std::is_lt(std::weak_order(str2, str1))) std::cout << str2 << " < " << str1 << std::endl;
if (std::is_lteq(std::weak_order(str2, str1))) std::cout << str2 << " <= " << str1 << std::endl;
if (std::is_gt(std::partial_order(str1, str2))) std::cout << str1 << " > " << str2 << std::endl;
if (std::is_gteq(std::partial_order(str1, str3))) std::cout << str1 << " >= " << str3 << std::endl;
return 0;
}
GitHub:https://github.com/fengbingchun/Messy_Test