簡單來將,仿函式(functor)就是乙個過載了"()"運算子的struct或class,利用物件支援operator()的特性,來達到模擬函式呼叫效果的技術。
我們平時對乙個集合類遍歷的時候,例如vector,是這樣做的:
1 for(vector::const_iterator iter = ivec.begin(); iter != ivec.end(); ++iter)2
例如下面的**:
1 #include 2 #include 34 struct state
5 7 ~state()
8 9 void setstate( int state )
10 int getstate() const
11 12 void print() const
13 14 private:
15 int m_state;
16 };
17 18 int main()
19 33
34
35 system( "pause" );
36 return 0;
37 }
這裡的for迴圈語句有點冗餘,想到了std::for_each ,為了使用for_each,我們需要定義乙個函式,如下:
void print( state* pstate )
於是就可以簡化為下面**:
std::for_each( vect.begin(), vect.end(),&print );
上面這段**有點醜陋,看起來不太爽,主要是函式指標的原因。
在這種應用環境下,c++有仿函式來替代,我們定義乙個仿函式,如下:
struct printer
};於是就可以簡化為下面**:
std::for_each( vect.begin(), vect.end(), printer() );
下面,我們初步看下 for_each 的stl原始碼實現:
1 template2 function for_each(inputiterator first, inputiterator last, function f)3
它返回f已在演算法內部變動過的乙個副本。
f可以是普通函式,也可是仿函式。它的任何返回值都將被忽略。
其實for_each就是乙個模板函式,將for迴圈語句封裝起來,前面兩個引數都是迭代器,第三個引數是使用乙個函式指標(或仿函式),其功能是對每乙個迭代器所指向的值呼叫仿函式。
上面**還是有點冗餘,因為為了使用for_each還要單獨定義乙個函式(或仿函式),不太清爽,
呵呵,stl早為我們準備好了 mem_fun 模板函式來解決這個乙個問題,於是**再次簡化為:
std::for_each( vect.begin(), vect.end(), std::mem_fun( &state::print ) );
我們一起看看 mem_fun 的stl原始碼實現:
1 // template function mem_fun2 templateinline
4 mem_fun_t<_result, _ty> mem_fun(_result (_ty::*_pm)())
5
8 9 mem_fun 函式實際上是呼叫 mem_fun_t 函式,我們接著深入看看 mem_fun_t,
10 11
12 // template class mem_fun_t
13 template15 class mem_fun_t
16 : public unary_function<_ty *, _result>
17
23 24 _result operator()(_ty *_pleft) const
25
28 private:
29 _result (_ty::*_pmemfun)(); // the member function pointer
30 };
31 32 將上面這段**定義的寫的我們好看懂一點,如下:
33 34 // template class mem_fun_t
35 template< typename _result, typename _ty >
36 class mem_fun_t : public unary_function<_ty *, _result>
37 44
45 _result operator()(_ty *_pleft) const
46
49 50 private:
51 _pmemfun m_pfun; // the member function pointer
52 53 };
這樣就比較清晰了,定義了仿函式mem_fun_t內部定義了乙個類成員函式指標,仿函式構造的時候將函式指標儲存起來,當仿函式operator()被呼叫的時候,就通過與乙個類的例項關聯起來從而實現了類成員函式的呼叫。
其呼叫流程是這樣的,for_each把vector中的元素傳送給mem_fun,mem_fun自己產生乙個仿函式mem_fun_t,然後仿函式呼叫其過載的()。
上述原始碼還有最後乙個沒有說明,就是unary_function,直接上原始碼:
1 // template struct unary_function2 template4 struct unary_function
5 ;
就乙個模板結構體。沒有資料成員,非常簡單。
最後,定義乙個刪除指標的仿函式:
struct deletepointer
};然後呼叫,就乙個逐一刪除vector裡面的所有元素了。
std::for_each( vect.begin(), vect.end(), deletepointer() );
STL演算法之for each
轉接自stl演算法 for each 對區間裡每個元素執行相應操作 注 for each 接受乙個操作,操作可改動所接受實參 所以該實參必須以by reference方式傳遞 include include include using namespace std for each 對區間裡每個元素執...
STL之演算法
演算法是指解決問題的方 而完整的描述,對於規範的輸入,在有限時間內要獲得所需要的輸出。不同的演算法可能使用不同的時間 空間或效率完成同樣的任務。想要評估乙個演算法的好壞,目前可以通過時間複雜度和空間複雜度來進行衡量。時間複雜度,是指演算法執行指令所需的計算量。演算法的執行時間和其所要處理的資料之間存...
STL之排序演算法
1.merge 以下是排序和通用演算法 提供元素排序策略 merge 合併兩個有序序列,存放到另乙個序列。例如 vecinta,vecintb,vecintc是用vector宣告的容器,vecinta已包含1,3,5,7,9元素,vecintb已包含2,4,6,8元素 vecintc.resize ...