std::all_of判断容器是否全满足条件,核心是谓词逻辑与合法迭代器范围;空容器返回true,谓词须为纯函数且类型匹配,避免与any_of/none_of混淆。

std::all_of 判断容器是否全满足条件,核心是传对谓词
它不关心容器类型,只看迭代器范围和谓词逻辑。用错谓词或迭代器范围,结果就不可靠。
- 谓词必须是可调用对象:
lambda、函数指针、重载了operator()的仿函数都行,但不能是普通变量或未定义的标识符 - 迭代器范围要合法:
begin和end必须来自同一容器,且end不能早于begin(空容器除外) - 常见错误现象:
std::all_of(v.begin(), v.end(), nullptr)直接编译失败;std::all_of(v.begin(), v.begin() + 10, ...)在v.size() 时触发未定义行为
lambda 谓词写法要注意捕获和返回类型
捕获外部变量时,若修改了原值又用于判断,容易误判;返回类型必须能隐式转为 bool,否则编译报错。
- 推荐显式写
-> bool,避免模板推导歧义:[x](int a) -> bool { return a > x; } - 不要在谓词里改容器元素:谓词应是纯函数,
std::all_of不保证执行顺序,也不承诺只调用一次 - 使用
auto推导参数类型时,注意底层 const/volatile 修饰——比如std::vector<const int></const>传进来的就是const int&,写成(int& a)会编译不过
和 std::any_of / std::none_of 的行为边界要分清
三者都短路求值,但语义完全不同。混用会导致逻辑翻车,尤其在条件取反场景下。
-
std::all_of(c.begin(), c.end(), pred)等价于 “没有一个元素不满足pred”,不是 “所有都返回 true” 的直觉叠加 - 空容器时,
std::all_of返回true(逻辑上“ vacuously true”),而std::any_of返回false——这点常被忽略,导致边界 case 漏测 - 别用
!std::any_of(..., std::not_fn(pred))替代std::all_of:多一层包装,性能无优势,还可能因std::not_fn的 SFINAE 行为引发意外编译失败
性能与迭代器类型的关系很实际
算法本身开销极小,但谓词复杂度和迭代器移动成本才是瓶颈。随机访问迭代器快,但输入迭代器(如 std::istream_iterator)只能单向走一次。
立即学习“C++免费学习笔记(深入)”;
- 对
std::list或std::forward_list,std::all_of时间仍是 O(n),但每次++it是指针跳转,比std::vector的地址加法慢一点 - 如果谓词本身有副作用(比如日志打印),别指望它被优化掉——标准不禁止实现缓存结果,但没人这么干,每次迭代都会调用
- 编译器通常能把简单 lambda 内联,但若谓词调用了虚函数或动态库符号,就失去内联机会,这时提前把判断逻辑收口到本地变量里反而更可控
最容易被忽略的是空容器的返回值,以及谓词中对非常量引用的误用——比如拿 int& 去接 const int 容器的元素,编译器不会帮你静默转换。











