區別的話這裡不多講,自己百度咯.
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是執行的操作(函數)