std::midpoint 是 C++20 引入的安全中点计算函数,避免 (a + b) / 2 的整数溢出问题,语义等价于 ⌊(a+b)/2⌋,要求同类型参数且不支持浮点数。

std::midpoint 是什么,为什么不用 (a + b) / 2
std::midpoint 是 C++20 引入的工具函数,定义在 头文件中,用于安全计算两个整数或指针的中点值。它解决的核心问题是:(a + b) / 2 在有符号整数上可能溢出(例如 INT_MAX + 1),而 std::midpoint 通过位运算或分段逻辑规避该问题,保证结果始终在合法范围内且数学上等价于向下取整的中点(即 ⌊(a+b)/2⌋)。
如何正确调用 std::midpoint:类型约束与常见编译错误
该函数是函数模板,要求两个参数类型相同,且必须是可比较、可进行算术运算的类型(如 int、long long、指针)。不支持浮点数(C++20 标准未定义浮点重载),也不支持混合类型(如 int 和 unsigned)。
- ✅ 正确:
std::midpoint(10, 20)、std::midpoint(ptr1, ptr2) - ❌ 编译失败:
std::midpoint(10U, 20)(无符号 vs 有符号)、std::midpoint(1.5, 2.5)(浮点数)、std::midpoint(a, b + 1)(若b + 1溢出,表达式本身已 UB,不进入midpoint) - ⚠️ 注意:必须启用 C++20 或更高标准(如
-std=c++20),否则链接不到或触发 SFINAE 失败
整数中点行为细节:向下取整、负数与边界情况
std::midpoint(a, b) 的语义是 (a + b) / 2 的安全替代,但结果始终等于 a + (b - a) / 2(使用无溢出的差值除法),因此对负数也保持一致:向零取整?不是——它是向负无穷取整(即 floor division)。例如:
std::midpoint(-3, 2) == -1 // (-3 + 2) / 2 = -0.5 → floor → -1 std::midpoint(-4, -1) == -3 // (-4 + -1) / 2 = -2.5 → floor → -3 std::midpoint(0, 1) == 0 // 不是 0.5,因为返回整型
- 结果类型与参数类型完全一致(不提升)
- 当
a > b时仍有效,结果为⌊(a+b)/2⌋,可能小于两者(如std::midpoint(5, 1) == 3) - 对指针,仅支持同数组内指针(或 one-past-the-end),否则行为未定义
实际使用建议与容易忽略的坑
它不是万能“平均值”函数,而是专为二分查找、内存布局、索引计算等需要严格中点语义的场景设计。别把它当成通用平均工具。
立即学习“C++免费学习笔记(深入)”;











