std::all_of判断容器所有元素是否满足条件,空容器返回true,短路求值,语义清晰且与手写循环性能相当;需注意迭代器范围、谓词参数类型匹配及避免捕获已销毁变量。

std::all_of 用来判断容器所有元素是否满足条件
它不修改容器,只返回 bool:全部满足返回 true,任一不满足就立刻返回 false。底层是短路求值,性能比手写循环好不了多少,但语义清晰、不易出错。
必须传入迭代器范围和谓词函数
调用格式固定为:std::all_of(first, last, pred),其中:
-
first和last是前闭后开区间(last不参与判断) -
pred可以是 lambda、函数指针、函数对象,参数类型要匹配容器元素类型 - 若容器为空,
std::all_of直接返回true(逻辑上“空集满足任意条件”)
std::vector<int> v = {2, 4, 6, 8};
bool all_even = std::all_of(v.begin(), v.end(), [](int x) { return x % 2 == 0; }); // true
<p>std::list<std::string> words = {"hello", "world", "cpp"};
bool all_longer_than_2 = std::all_of(words.begin(), words.end(), [](const std::string& s) {
return s.length() > 2;
}); // true</p>常见错误:迭代器类型不匹配或越界
编译失败或运行时未定义行为往往源于:
- 对
std::array或原生数组误用.begin()(需用std::begin(arr)) - 传入
end() - 1当作last—— 错,应始终用end() - 谓词捕获了已销毁的局部变量(lambda 中用
[&]引用栈变量后容器生命周期更长) - 对
std::map使用时,谓词参数类型得是std::pair<const key value></const>,不是裸Value
std::map<int, std::string> m = {{1,"a"}, {2,"b"}};
// ❌ 编译失败:lambda 参数不能是 std::string
// std::all_of(m.begin(), m.end(), [](std::string s) { return !s.empty(); });
<p>// ✅ 正确:解构 pair 或访问 second
std::all_of(m.begin(), m.end(), [](const auto& p) { return !p.second.empty(); });</p>与手写循环对比:可读性胜于微优化
有人担心 STL 算法有函数调用开销,实际在 -O2 下,std::all_of 和等效 for 循环生成的汇编几乎一致。真正差异在于:
立即学习“C++免费学习笔记(深入)”;
- 少写边界判断(比如空容器、单元素)
- 避免手抖写成
&&误为||的逻辑翻车 - 配合
auto和 lambda,泛型代码更紧凑
唯一要注意的是:如果谓词本身很重(比如涉及磁盘 IO 或锁),那提前退出的价值才真正凸显 —— 这时候 std::all_of 的短路特性就不是“锦上添花”,而是关键行为。










