for_each(),从它的名称可以大概猜测出它的作用,对每个元素执行某操作。书上写的是“它将调用者提供的操作施加于每一个元素身上”。
for_each()算法非常灵活,它可以用不同的方式存取、处理、修改每一个元素。
UnaryProc for_each(InputIterator beg,InputIterator end,UnaryProc op)
- 对区间[begin,end)中的每一个元素调用 op(elem)
- 返回 op(已经在算法内部被改动过)的一个副本
- op可以是变动元素,也可以是非更易型操作(不改变元素的值,比如显示等操作)
- op的任何返回值都会被忽略
下面第一个例子我们展示用for_each()打印vector中的元素。
将Print()传给for_each,使得for_each()对每一个元素调用Print(),从而打印所有元素
#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
void Print(int a)
{
cout << a << " ";
}
template <typename T>
void INSERT_ELEMENT(vector<T>& v, int a, int b)
{
for (int i = a; i <= b; ++i)
{
v.push_back(i);
}
}
int main()
{
vector<int> col;
INSERT_ELEMENT(col, 1, 9);
for_each(col.begin(), col.end(), Print);
cout << endl;
}
运行结果如下
第二个例子我们通过for_each()算法配合仿函数来改变每一个元素内容
#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
void Print(int a)
{
cout << a << " ";
}
template <typename T>
void INSERT_ELEMENT(vector<T>& v, int a, int b)
{
for (int i = a; i <= b; ++i)
{
v.push_back(i);
}
}
template<class S>
class AddValue
{
private:
S theValue;
public:
AddValue(const S& v):theValue(v)
{ }
void operator()(S& elem)const
{
elem += theValue;
}
};
int main()
{
vector<int> col;
INSERT_ELEMENT(col, 1, 9);
cout << "add 10 to each elem: ";
for_each(col.begin(), col.end(), AddValue<int>(10));
for_each(col.begin(), col.end(), Print);
cout << endl;
cout << "add the first value in col, to each elem: ";
for_each(col.begin(), col.end(), AddValue<int>(*col.begin()));
for_each(col.begin(), col.end(), Print);
cout << endl;
}
运行结果如下
第三个例子展示如何利用for_each()的返回值,它可以返回其仿函数, 由于for_each()能够返回一项操作,可以利用这一特性在该操作中处理返回结果
#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
void Print(int a)
{
cout << a << " ";
}
template <typename T>
void INSERT_ELEMENT(vector<T>& v, int a, int b)
{
for (int i = a; i <= b; ++i)
{
v.push_back(i);
}
}
class MeanValue
{
private:
long num;
long sum;
public:
MeanValue():num(0),sum(0){}
void operator()(int elem)
{
num++;
sum += elem;
}
operator double()
{
return static_cast<double>(sum) / static_cast<double>(num);
}
};
int main()
{
vector<int> col;
INSERT_ELEMENT(col, 1, 9);
for_each(col.begin(), col.end(), Print);
double mv=for_each(col.begin(), col.end(), MeanValue());
cout << endl;
cout << "mean value: " << mv << endl;
}
运行结果如下:
在这个程序中需要注意到有一个语句
operator double()
这个其实也是一个操作符重载,但是它看起来和我们平常见到的不一样,这是一个类型转换用到的。
隐式类型转换运算符只是一个样子奇怪的成员函数,operator 关键字后面跟一个类型符号。不用定义函数的返回类型,因为返回类型就是这个函数的名字,例如我们上面写到的MeanValue类,
允许MeanValue类隐式地转换成double类型,
operator double()
还有就是static_cast是一个强制类型转换操作符,编译器隐式执行地任何类型转换都可以由static_cast来完成。
return static_cast<double>(sum) / static_cast<double>(num);