std::for_each
先贴cppreference中对for_each的概述:
template< class InputIt, class UnaryFunction > //此处UnaryFunction为一元函数 UnaryFunction for_each( InputIt first, InputIt last, UnaryFunction f );
1) Applies the given function objectf
to the result of dereferencing every iterator in the range[first, last)
, in order. //in order按顺序2) Applies the given function objectf
to the result of dereferencing every iterator in the range[first, last)
(not necessarily in order). The algorithm is executed according topolicy
. This overload does not participate in overload resolution //policy政策 //participate参加//overload resolution重载决议unless std::is_execution_policy_v<std::decay_t<ExecutionPolicy>> is true.//这句话暂时不需要懂,cpp17对for_each又增加了一个重载版本而已For both overloads, ifInputIt
is a mutable iterator,f
may modify the elements of the range through the dereferenced iterator. Iff
returns a result, the result is ignored. //如果迭代器不是const的,则允许一元函数对解引用的对象进行修改。如果一元函数返回一个值,则返回值被忽略.
f | - | function object, to be applied to the result of dereferencing every iterator in the range [first, last) The signature of the function should be equivalent to the following: void fun(const Type &a); The signature does not need to have const &. |
for_each返回值为第三个参数,即仿函数。即通过for_each可以获得操作后的对象状态。
贴一段用for_each清零数组的小程序:
#include <iostream> #include <algorithm> #include <vector> using namespace std; int main() { const int elementSize = 10;
vector<int> vec(elementSize, 1);
for_each(begin(vec), end(vec), [&] (int &i) { i = 0; } ); //引用捕获方式,将每个值置0 for(const auto &j : vec) //范围for循环打印 cout << j << " "; cout << endl; return 0; }
微软社区的一个示例:
// alg_for_each.cpp // compile with: /EHsc #include <vector> #include <algorithm> #include <iostream> // The function object multiplies an element by a Factor template <class Type> class MultValue { private: Type Factor; // The value to multiply by public: // Constructor initializes the value to multiply by MultValue ( const Type& _Val ) : Factor ( _Val ) { } // The function call for the element to be multiplied void operator ( ) ( Type& elem ) const //重载成可调用对象,要注意当此可调用对象需要传参时,需要额外加一个形参列表,且应该放在 () 的后面。 { elem *= Factor; } }; // The function object to determine the average class Average { private: long num; // The number of elements long sum; // The sum of the elements public: // Constructor initializes the value to multiply by Average ( ) : num ( 0 ) , sum ( 0 ) { } // The function call to process the next elment void operator ( ) ( int elem ) { num++; // Increment the element count sum += elem; // Add the value to the partial sum } // return Average operator double ( ) //转换操作符重载 { return static_cast <double> (sum) / static_cast <double> (num); } };
//以下我基于范围for循环重写了一部分 int main( ) {
using namespace std;
vector<int> vec;
vector<int>::iterator iter;
int i;
for( i = -4; i <= 2; ++i) //给数组赋一个初始序列
{
vec.push_back(i);
}
cout << "The original sequence is ("; //打印初始序列
for(const auto &num : vec)
{
cout << num << " ";
}
cout << ")." << endl;
for_each(vec.begin(), vec.end(), MultValue<int>(-2)); //将序列中的值依次乘以-2
cout << "The mod1 sequence is ("; //打印mod1序列
for(const auto &num : vec)
{
cout << num << " ";
}
cout << ")." << endl;
for_each(vec.begin(), vec.end(), MultValue<int>(5)); //将序列中的值依次乘以5
cout << "The mod2 sequence is ("; //打印mod2序列
for(const auto &num : vec)
{
cout << num << " ";
}
cout << ")." << endl;
double ret = for_each(vec.cbegin(), vec.cend(), Average()); //求平均值。此处用重载double操作符实现,比较难以理解。可以用如下改法:
/* Average tmp = for_each(vec.cbegin(), vec.cend(), Average());
cout << tmp.xxx << endl; //将operator double () 改为 double xxx() { return static_cast<double>(sum) / static_cast<double>(num); }
*/
cout << "The average of mod2 is :" //打印平均值
<< ret << endl;
return 0; }
The original sequence is (-4, -3, -2, -1, 0, 1, 2).
The mod1 sequence is (8, 6, 4, 2, 0, -2, -4).
The mod2 sequence is (40, 30, 20, 10, 0, -10, -20).
The average of mod2 is :10
此处补一下转换操作符重载的知识:
class <类型1> {
public: operator <类型2> () { } };
由此可见:转换操作符重载就是将类型1转换为类型2
#include <iostream> using namespace std; class Ratation { private: long num_; long sum_; public: Ratation() : num_(2), sum_(1) { } operator double () { return static_cast <double> (sum_) / static_cast <double> (num_); } }; int main() { Ratation obj; double a = 1.2; a += Ratation(); //执行Ratation到double的转换 cout << a << endl; //此处输出1.7,可见Ratation被转换为双精度了。 return 0; }
参考:http://en.cppreference.com/w/cpp/algorithm/for_each
https://msdn.microsoft.com/zh-cn/library/e5sk9w9k.aspx
写于 : 2017-03-04 23:08:37