最常见方式是 a == b && b == c;C++ 不支持 a == b == c,因会先算 a == b 得 0/1 再与 c 比较;需注意类型一致、浮点数用误差判断、自定义类型重载 operator== 并满足等价关系。

直接用 == 比较三个数是否相等
最常见也最直接的方式是写 a == b && b == c。C++ 中没有三元等值运算符(比如 Python 的 a == b == c),所以不能写成 a == b == c——这会先算 a == b 得到 true 或 false(即 1 或 0),再跟 c 比较,结果完全不可靠。
实际使用时注意:
-
a、b、c类型要一致或可隐式转换,否则可能触发意外的类型提升(比如int和double比较) - 浮点数慎用
==,应改用误差范围判断(见下一条) - 自定义类型需重载
operator==,且保证其满足自反性、对称性、传递性
浮点数比较必须用 abs(diff)
直接用 == 判断 float 或 double 是否相等几乎总是错的,因为浮点计算存在舍入误差。正确做法是检查差值的绝对值是否小于一个极小阈值。
例如:
立即学习“C++免费学习笔记(深入)”;
double a = 0.1 + 0.2; double b = 0.3; double c = 0.3; bool all_equal = (std::abs(a - b) < 1e-9) && (std::abs(b - c) < 1e-9);
关键点:
- 别用固定
1e-9硬编码,更稳妥的是用std::numeric_limits<double>::epsilon()做相对误差(尤其当数值很大或很小时) - 不要写成
std::abs(a - b) 这类形式来处理 <code>b == 0的情况,得单独分支或用std::max(1.0, std::abs(b))归一化 - 如果三个数都是
NaN,任何比较都返回false,包括NaN == NaN,需额外用std::isnan()处理
模板函数封装可复用的三值等值判断
重复写 a == b && b == c 容易出错,也难维护。可以封装成函数模板,支持任意可比较类型,并自动处理浮点特例。
简单版本示例:
template <typename T>
bool are_equal(T a, T b, T c) {
if constexpr (std::is_floating_point_v<T>) {
auto eps = std::numeric_limits<T>::epsilon() * 10;
return std::abs(a - b) < eps && std::abs(b - c) < eps;
} else {
return a == b && b == c;
}
}使用时注意:
-
if constexpr要求 C++17 及以上;若用旧标准,得用 SFINAE 或函数重载 - 该模板不处理用户自定义浮点类,只覆盖内置
float/double/long double - 传入引用(
const T&)更安全,避免大对象拷贝,但模板推导时要注意 const/volatile 修饰
宏或 constexpr 函数不适合做通用判断
有人想用宏如 #define EQUAL3(a,b,c) ((a)==(b) && (b)==(c)) 图省事,但宏有严重隐患:
- 参数带副作用会出错,比如
EQUAL3(i++, i++, i++)行为未定义 - 无法做类型检查,编译器不会报类型不匹配错误
- 调试时看不到宏展开逻辑,堆栈里只有原始调用行号
而 constexpr 函数虽能编译期求值,但对浮点数仍受限于 IEEE 754 表达精度——constexpr double x = 0.1 + 0.2; 在不同编译器上可能生成不同 bit 模式,导致 constexpr 版本在编译期就“误判”。
真正需要编译期判断三个整型常量是否相等?用 static_assert(a == b && b == c, "...") 更直接可靠。


















