std::all_of
1. 概述
std::all_of 是 C++11 引入的算法,用于判断给定范围内的所有元素是否都满足某个一元谓词(unary predicate)。如果范围为空,则返回 true。
2. 头文件
要使用 std::all_of,需包含:
#include <algorithm>
如果使用并行版本,还需:
#include <execution> // C++17 并行执行策略
如果使用 C++20 的 ranges 版本,还需:
#include <algorithm> // C++20 起包含 ranges 版
#include <ranges>
3. 函数原型
C++11–C++17 传统版本
template <class InputIt, class UnaryPredicate>
bool all_of(InputIt first, InputIt last, UnaryPredicate p);
-
InputIt:满足输入迭代器(InputIterator)要求。
-
UnaryPredicate:可调用对象,签名可转为 bool(const typename std::iterator_traits::value_type&)。
C++17 并行版本
template <class ExecutionPolicy, class ForwardIt, class UnaryPredicate>
bool all_of(ExecutionPolicy&& policy, ForwardIt first, ForwardIt last, UnaryPredicate p);
- ExecutionPolicy:如 std::execution::seq(顺序)、par(并行)、par_unseq(并行向量化)。
C++20 ranges 版本
template <std::ranges::input_range Range, class UnaryPredicate>
bool all_of(Range&& r, UnaryPredicate p);
- 第一个参数可以直接传入容器或其他 Range 对象。
4. 行为与返回值
-
行为:从 first 开始依次应用谓词 p,只要有一次返回 false,算法立刻结束并返回 false;否则遍历结束后返回 true。
-
空范围:若 first == last,不调用谓词,直接返回 true。
-
返回:bool,表示“是否所有元素都满足谓词”。
5. 复杂度
-
调用谓词次数 ≤ last - first。
-
最坏情况下需遍历整个区间;遇到不满足的元素可提早退出。
6. 示例代码
6.1 检查整数序列是否全为正数
#include <algorithm>
#include <vector>
#include <iostream>
int main() {
std::vector<int> v{ 1, 2, 3, 4, 5 };
bool all_positive = std::all_of(v.begin(), v.end(),
[](int x){ return x > 0; });
std::cout << std::boolalpha
<< "All positive? " << all_positive << "\n";
}
6.2 并行版示例(C++17)
#include <algorithm>
#include <execution>
#include <vector>
int main() {
std::vector<int> large_data = /* … */;
bool ok = std::all_of(std::execution::par,
large_data.begin(),
large_data.end(),
[](int x){ return x % 2 == 0; });
// 并行检查所有元素是否为偶数
}
6.3 Ranges 版示例(C++20)
#include <algorithm>
#include <ranges>
#include <vector>
int main() {
std::vector<double> data{ 0.1, 0.2, 0.3 };
bool small = std::all_of(data, [](double x){ return x < 1.0; });
// 直接传容器,无需显式迭代器
}
7. 与手写循环对比
bool all = true;
for (auto it = first; it != last; ++it) {
if (!p(*it)) {
all = false;
break;
}
}
// 等价于 std::all_of(first, last, p);
std::all_of 提供了更简洁、易读且可接受并行执行策略的接口。
8. 注意事项
-
空区间返回 true:符合“所有元素都……(对于零个元素也成立)”的数学定义。
-
谓词副作用:若谓词有副作用(修改外部状态),并行版本可能产生数据竞态。
-
迭代器要求:
-
传统版只需输入迭代器。
-
并行版需前向迭代器(ForwardIterator)及以上。
-
异常安全:若谓词抛异常,算法不会捕获,调用者需自行处理。
-
选择合适版本:简单范围检查用传统版;大数据、性能敏感可考虑并行;C++20 可利用 ranges 版提高可读性。