区别的话这里不多讲,自己百度咯.
for_each(begin,end,function);
先看一个简单易理解的小例子
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
void print(int elem)
{
cout << elem << ' ';
}
int main()
{
vector<int> coll;
for(int i = 1; i <= 10; ++i)
coll.push_back(i);
for_each(coll.begin(),coll.end(),print);
cout << endl;
return 0;
}
自己运行一下,没有用for()语句来输出是不是显得很清爽?
再来看一个例子
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
void show(int number) //将排序后的数字输出
{
cout<<number<<endl;
}
int main()
{
vector<int> getnumber;
int x;
int i=0;
do{
cout<<"please enter a number,when you enter 0,this will end"<<endl;
cin>>x;
getnumber.push_back(x);
}while(x!=0);
int j=getnumber.size();
int t;
for(i=0;i<j;i++)
{
for(int m=j-1;m>i;m--)
{
if(getnumber[m-1]>getnumber[m])
{
t=getnumber[m-1];
getnumber[m-1]=getnumber[m];
getnumber[m]=t;
}
}
}
cout<<"the result:"<<endl;
for_each(getnumber.begin(),getnumber.end(),show);
return 0;
}
for_each第一个参数和第二个参数是指定范围的.至于第三个参数,如果是容器,那么参数就是容器,如果是数组,就写指针,第三个参数的调用函数的名字,就是说对于第一个参数和第二个参数指定范围之中的每一个元素都会带入到第三个参数指定的函数中去。
对STL的容器中,遍历是一个非常经常采用的动作,为此STL也提供一个算法,for_each
遍历一个容器,我们第一个想到的是
for (int i = 0;i < a.size();++i)
的循环来实现。
这样做有几个弊端,比如我现在很多地方用vector作为传引用参数进行传递,为了减少对象构造和析构的代价,我一般采用指针来传递,那么我就要在程序很多地方 写上类似下面的代码
for (int i=0;i < a.size();++i)
delete a[i];
虽然代码很多都一样,可是到处泛滥着这种循环语句,让人阅读程序容易和其它释放指针行为产生混淆
而改用for_each实现
如下面sample
#include <algorithm>
#include <deque>
using namespace std;
template<class T>
class deletePtr
{
public:
int operator()(T *t)
{
printf("%d\n",*t);
delete t;
}
};
deletePtr <int> deleteIntPtr;
int main()
{
deque<int* > xxx;
xxx.push_back(new int(1));
xxx.push_back(new int(2));
xxx.push_back(new int(3));
xxx.push_back(new int(4));
xxx.push_back(new int(5));
for_each(xxx.begin(),xxx.end(),deleteIntPtr);
}
好处有几个:
1:for_each调用容器内部的遍历函数,比我们的++的方式遍历,效率不会低是肯定的
2:delete指针时候,可以再次确认指针类型
3:用仿函数类,编译器在编译期对函数进行展开,实际上没有函数调用的发生
4:加强代码自说明能力,减少循环,提高代码可读性
STL真的很优雅,我发现MFC的那些容器类,除了个CString外,其它的基本没STL原有的容器类好用,而且可移植性STL也具有很大优势。
#include <iostream>
#include <algorithm>
#include <list>
using namespace std;
class T1
{
public:
virtual void S1()=0;
virtual void S2()=0;
};
class T2 : public T1
{
public:
virtual void S1() {
printf("T2:S1\n");
}
virtual void S2() {
printf("T2:S2\n");
}
};
class T3_1 : public T2
{
public:
virtual void S1() {
printf("T3_1:S1\n");
}
};
class T3_2 : public T2
{
public:
virtual void S1() {
printf("T3_2:S1\n");
}
virtual void S2() {
printf("T3_2:S2\n");
}
};
int main()
{
typedef list<T1 *> TSTTB;
TSTTB list1;
list1.push_back(new T2());
list1.push_back(new T3_1());
list1.push_back(new T3_2());
printf("T2-T3_1-T3_2\n===============================================\n");
printf("调用&T1::S1\n===============================================\n");
for_each(list1.begin(), list1.end(), mem_fun(&T1::S1));
printf("调用&T1::S2\n===============================================\n");
for_each(list1.begin(), list1.end(), mem_fun(&T1::S2));
return 0;
}
关于transform
例如 std::string sl = "hello"; std::transform(sl.begin(), sl.end(), sl.begin(), toupper); 这样得到 sl 值是 大写的 HELLOtransform 是遍历一个容器里面元素 然后执行一个操作第1和2个参数是数据起始和结束位置(迭代器)参数3是写入目标的起始位置参数4是执行的操作(函数)