std::minmax是C++11引入的算法,单次遍历同时返回最小值和最大值(.first为最小,.second为最大),避免对单向迭代器重复遍历,返回值而非迭代器,需包含且不可用于空范围。

std::minmax 是什么,为什么不用两次调用 std::min 和 std::max
std::minmax 是 C++11 引入的实用算法,用于**单次遍历**同时返回最小值和最大值。相比分别调用 std::min 和 std::max(会遍历容器两次),它对迭代器范围只需一次比较 —— 对 std::vector、数组等随机访问容器,性能提升不明显;但对 std::list 或输入流这类仅支持单向遍历的序列,**避免重复遍历是关键优势**。
它返回一个 std::pair,其中 .first 是最小值,.second 是最大值(注意不是按升序排列的 pair,而是固定语义)。
如何正确调用 std::minmax(含常见编译错误)
必须包含头文件 ,且需启用 C++11 或更高标准(如编译时加 -std=c++11)。常见错误包括:
- 忘记
#include→ 报错:‘minmax’ was not declared in this scope - 用在 C++98 模式下 → 编译失败,无回退机制
- 传入空范围(如空 vector 的
begin()/end())→ 行为未定义,**不会抛异常,也不会断言**,务必提前检查
基础用法示例:
立即学习“C++免费学习笔记(深入)”;
#include#include #include std::vector v = {3, 1, 4, 1, 5}; auto p = std::minmax(v.begin(), v.end()); std::cout << "min=" << *p.first << ", max=" << *p.second << "\n"; // 输出:min=1, max=5
std::minmax 与 std::minmax_element 的区别
这是最容易混淆的一对函数:
-
std::minmax:直接返回**值本身**(要求元素可拷贝/移动),适用于小对象或需要值的场景 -
std::minmax_element:返回**迭代器**(指向最小/最大元素的位置),适用于大对象(避免拷贝)、需要修改原容器元素、或需获取索引位置的场景
例如,想把最大值改成 0,必须用 std::minmax_element:
auto it_pair = std::minmax_element(v.begin(), v.end()); *it_pair.second = 0; // OK:通过迭代器修改 // *std::minmax(v.begin(), v.end()).second = 0; // 错误:返回的是临时值,不可赋值
自定义比较逻辑与性能注意事项
std::minmax 支持传入二元谓词(比如按绝对值比较):
std::vectorv = {-5, 3, -1, 4}; auto p = std::minmax(v.begin(), v.end(), [](int a, int b) { return std::abs(a) < std::abs(b); }); // p.first 指向 -1(abs=1),p.second 指向 -5 或 5(abs=5)
注意点:
- 比较函数必须满足严格弱序(strict weak ordering),否则行为未定义
- 对于
std::initializer_list,有重载版本std::minmax({1,2,3}),返回std::pair,引用绑定到临时 list,生命周期安全 - 若只关心最大最小值之一,别硬套
std::minmax—— 单次调用std::min_element或std::max_element更清晰,也更易被编译器优化
真正容易被忽略的是:当元素类型重载了 operator 但语义不稳定(比如浮点数 NaN 比较),std::minmax 的结果可能不符合直觉,此时应显式传入稳定谓词或预处理 NaN。











