在 C++20 标准中,最常见的新增特性之一是三方运算符(三元比较运算符),即 std::cmp_less, std::cmp_equal, std::cmp_greater 等。这些运算符是为了在不同类型之间进行比较时,避免出现隐式转换导致的误判,从而提高代码的类型安全性与可读性。
一、三方运算符的语法
#include <compare>
int a = 5;
int b = 10;
// 传统三元运算符
if (a < b) { /* ... */ }
// C++20 三方运算符
if (std::cmp_less(a, b)) { /* ... */ }
这些运算符会返回 std::strong_ordering, std::weak_ordering, 或 std::partial_ordering 对象,后者可以直接在布尔表达式中使用。
二、为什么要使用三方运算符?
-
避免隐式类型转换
传统<运算符在不同类型之间比较时可能会产生隐式转换,导致精度丢失或错误比较。三方运算符会在编译时捕获类型不匹配。 -
提升可读性
通过std::cmp_less、std::cmp_greater等命名,代码意图更加清晰。 -
支持自定义类型
若自定义类型实现了<=>或operator<=>,三方运算符可以直接调用,从而简化比较逻辑。
三、使用场景举例
1. 字符串与 C 字符串比较
#include <string>
#include <compare>
std::string s = "hello";
const char* cstr = "world";
if (std::cmp_less(s, cstr)) {
std::cout << s << " is less than " << cstr << '\n';
}
2. 枚举与整数比较
enum class Color { Red, Green, Blue };
Color c = Color::Green;
int val = 1;
if (std::cmp_equal(c, static_cast <Color>(val))) {
std::cout << "Same color\n";
}
四、注意事项
-
返回值类型
三方运算符返回的是std::strong_ordering、std::weak_ordering或std::partial_ordering,而不是bool。但它们可直接用于布尔上下文。 -
自定义类型
若实现了三向比较运算符(<=>),就可以直接使用std::cmp_*。否则需要提供显式的比较函数。 -
头文件
`,否则会报编译错误。
必须包含 `
五、实战案例:安全排序
#include <vector>
#include <compare>
#include <algorithm>
#include <iostream>
struct Person {
std::string name;
int age;
// 采用三向比较
auto operator<=>(const Person&) const = default;
};
int main() {
std::vector <Person> people = {
{"Alice", 30}, {"Bob", 25}, {"Charlie", 30}
};
std::sort(people.begin(), people.end(),
[](const Person& a, const Person& b) {
// 直接使用 std::cmp_less,避免比较错误
return std::cmp_less(a.age, b.age);
});
for (const auto& p : people) {
std::cout << p.name << ' ' << p.age << '\n';
}
}
此示例展示了如何在 std::sort 的比较函数中使用 std::cmp_less,提高了类型安全性。
六、结语
三方运算符是 C++20 标准对比较操作的一次重要改进。它们通过更严格的类型检查、语义清晰和兼容自定义类型,帮助开发者编写更安全、更易维护的代码。建议在新项目中优先使用三方运算符,逐步替代传统 <, >, == 等运算符,享受 C++20 带来的便利与性能提升。