std::for_each是中的函数模板,用于对区间内每个元素调用指定可调用对象,不支持break/continue,仅依次调用且返回函数对象副本。
std::for_each 是 头文件里的函数模板,作用是对区间内每个元素调用指定的函数对象(可调用物)。它不提供“遍历控制权”,也不支持提前跳出(除非抛异常),和 for 循环语义不同。
常见误用是把它当 for 写法的替代品来“控制流程”,结果发现不能 break、不能 continue、返回值无意义。它只做一件事:依次调用。
begin 和 end 迭代器(比如 v.begin(), v.end())
用 lambda 时最容易踩的是变量捕获方式错误。尤其修改外部变量或遍历容器本身时,[&] 和 [=] 行为差异极大。
例如想统计偶数个数:
int count = 0;
std::for_each(v.begin(), v.end(), [&count](int x) { if (x % 2 == 0) ++count; });
这里必须用 [&count] 或 [&],用 [=] 会捕获 count 的副本,外部 count 不变。
[](int& x) { x *= 2; }
const int& 更高效(避免拷贝大对象)for_each
两者生成的汇编通常一致,编译器能很好优化。区别主要在表达意图和维护成本。
for_each 更适合“把操作抽象成独立行为”的场景,比如复用同一个处理逻辑:for_each(a.begin(), a.end(), log_item) + for_each(b.begin(), b.end(), log_item)
for_each 做不到自然中断std::for_each 返回传入的函数对象(按值返回),不是 void。这个特性极少用,但可用于链式调用或检查状态(比如 functor 内部计数)。
例如:
struct Counter {
int n = 0;
void operator()(int) { ++n; }
};
Counter c = std::for_each(v.begin(), v.end(), Counter{});
// 此时 c.n 是容器大小(前提是没提前退出)
注意:返回的是副本,原对象状态未保留;若 functor 有状态且需后续访问,应传入左值引用或改用其他方式。
真正需要这种写法的场景极少见,多数时候只是白添复杂度。别为了“用 STL”而用 for_each —— 容器是否支持随机访问、操作是否纯、是否要异常安全,这些才决定该不该选它。