<p>std::midpoint 能避免整数溢出,因其采用 a + (b - a) / 2 等效算法而非 (a + b) / 2,绕过加法溢出;需 C++20 支持、<numeric> 头文件及类型严格匹配。</p>

std::midpoint 为什么能避免整数溢出
因为 std::midpoint 不用 (a + b) / 2 这种先加后除的逻辑,而是改用位运算或分段计算策略——对有符号整数,它等价于 a + (b - a) / 2(带向下取整调整),天然避开 a + b 可能越界的环节。比如 INT_MAX 和 1 求平均,(INT_MAX + 1) 直接溢出未定义行为,而 std::midpoint(INT_MAX, 1) 安全返回 INT_MAX。
必须包含 <numeric> 且编译器要支持 C++20
很多老项目默认没开 C++20,直接写会报 ‘midpoint’ is not a member of ‘std’。确认方法:检查编译器版本和标准选项。
- GCC/Clang 需加
-std=c++20或更高 - MSVC 需 VS2019 16.10+,且项目属性中设置
/std:c++20 - 头文件只写
#include <numeric>,不用<algorithm>或其他
std::midpoint 对类型有严格要求
它只接受「可相减且可右移」的算术类型,常见但易错的情况:
组合式C++代码评审方案,融合静态分析、AI推理、多轮迭代评审和C++专项检查,适用于PR审查、增量代码审查、全项目评审和代码质量评分,触发词包括review cpp、cpp代码评审、C++review、代码审查。
- 支持
int、long long、unsigned int,也支持指针(如int*) - 不支持
float或double—— 会编译失败,提示 no matching function - 两个参数类型必须完全一致,
std::midpoint(3LL, 5)错误;要写成std::midpoint(3LL, 5LL)或用static_cast - 对无符号类型,结果是向零取整;对有符号,是向负无穷取整(即 floor((a+b)/2.0))
替代方案对比:什么时候不该用 std::midpoint
它不是万能的。如果业务需要浮点精度、或输入本身是 double,硬转整数再调用反而引入误差。此时应明确用 (static_cast<double>(a) + b) / 2.0。
立即学习“C++免费学习笔记(深入)”;
- 求区间中点用于二分查找索引?优先用
std::midpoint,安全且语义清晰 - 做图形插值或物理模拟,需要小数部分?别用,它只返回整型结果
- 已有代码用宏
#define AVG(a,b) ((a)+(b))/2?不能直接替换为std::midpoint,因为宏可能接受表达式,而std::midpoint要求左值或字面量,需重构调用点
真正要注意的是:它不处理 NaN、无穷大,也不校验指针是否同属一个数组——这些得靠你自己的上下文约束。

















