std::for_each
用于逐个遍历容器元素,它对迭代器区间[first, last)
所指的每一个元素,执行由单参数函数对象f
所定义的操作。它是for循环的一种替代方案。
std::for_each
如需使用std::for_each
,需要引入头文件:
#include <algorithm>
std::for_each
函数定义:
template< class InputIt, class UnaryFunction >
UnaryFunction for_each(InputIt first, InputIt last, UnaryFunction f);
函数意义:按顺序应用给定的可调用对象f
到[first, last)
范围内每个迭代器的结果。
函数参数:
- first、last:应用函数的范围
- f:可调用对象,应用于范围[first, last]内每个迭代器的结果
对于可调用对象,其函数签名应等同于以下内容:
void fun(const Type &a);
其中,唯一参数也不一定要有const &
,但该可调用对象的返回值必须为void
。
函数返回值:传入的可调用对象的最终状态(C++11后,该返回值为右值)。
一般情况下,获得返回值常用于可调用对象为函数对象时(重载了()运算符类型的对象)。
根据语义,std::for_each
可能的一种实现是:
template<class InputIt, class UnaryFunction>
constexpr UnaryFunction for_each(InputIt first, InputIt last, UnaryFunction f)
{for (; first != last; ++first) {f(*first);}return std::move(f);
}
std::for_each的优越性
std::for_each更明确了整个循环语义,有利于编译器优化。它偏向于函数式编程,就是老老实实从first迭代到end,没有中途退出循环的break
,没有直接跳下一步循环的continue
。
这个语义清清楚楚,编译器可以尽情优化。相反,如果使用传统的for循环,或者C++11的range-based for,都无法让编译器相信半途中是否会来个break/continue这样的操作。
也就是说,编译器可以从for_each里获得更多的语义。而for循环把这些语义全搞丢了!
因此,std::for_each可以支持并行操作。C++17开始有并行的std::for_each重载了,目前msvc和gcc已经实现,clang还没有实现。
template< class ExecutionPolicy, class ForwardIt, class UnaryFunction2 >
void for_each(ExecutionPolicy&& policy, ForwardIt first, ForwardIt last, UnaryFunction2 f);
该函数:应用给定的可调用对象f到[first, last)范围内每个迭代器的结果(不必按顺序),按照policy执行算法。
policy指的是允许的并行类型,具体的类型种类可以参考:
- std::execution::seq, std::execution::par, std::execution::par_unseq, std::execution::unseq
std::for_each实例
#include <iostream>
#include <algorithm>
#include <vector>class Sum {public:Sum() : sum(0) {}~Sum() {}void operator()(int n) { sum += n; }int sum;
};int main()
{std::vector<int> nums{6, 8, 4, 10, 2, 12};auto print = [](int n) {std::cout << n << " ";};std::for_each(nums.begin(), nums.end(), print); // 打印std::cout << std::endl;std::for_each(nums.begin(), nums.end(), [](int &n) { // 每个数++++n;});std::for_each(nums.begin(), nums.end(), print); // 打印std::cout << std::endl;Sum s = std::for_each(nums.begin(), nums.end(), Sum()); // 求和std::cout << s.sum << std::endl;int sum = 0;std::for_each(nums.begin(), nums.end(), [&sum](int n) { // 求和sum += n;});std::cout << sum << std::endl;return 0;
}
编译并运行这段代码:
yngzmiao@yngzmiao-virtual-machine:~/test/foreach$ ./main
6 8 4 10 2 12
7 9 5 11 3 13
48
48
相关阅读
- C++ STL中 for_each 算法存在的意义是什么?
- std::for_each - cppreference.com
- C++中std::for_each的使用