一、函數對象
1、函數對象(function object)也稱為仿函數(functor)
2、一個行為類似函數的對象,它可以沒有參數,也可以帶有若幹參數。
3、任何重載了調用運算符operator()的類的對象都滿足函數對象的特征
4、函數對象可以把它稱之為smart function。
5、STL中也定義了一些标準的函數對象,如果以功能劃分,可以分為算術運算、關系運算、邏輯運算三大類。為了調用這些标準函數對象,需要包含頭檔案<functional>。
二、自定義函數對象
注意:CFunObj()(); 表示先構造一個匿名對象,再調用operator();
三、函數對象與容器
在這邊舉map 容器的例子,大家都知道map 在插入元素的時候會自動排序,預設是根據key 從小到大排序,看map 的定義:
假設現在我們這樣使用 map< int, string > mapTest; 那麼預設的第三個參數 _Pr = less<int>,再者,map 繼承的其中一個類
_Tmap_traits 中有個成員:
_Pr comp;// the comparator predicate for keys
跟蹤進insert 函數,其中有這樣一句:
if (_DEBUG_LT_PRED(this->comp, _Key(_Where._Mynode()), this->_Kfn(_Val)))
已知 #define _DEBUG_LT_PRED(pred, x, y) pred(x, y) 很明顯地,comp 在這裡當作函數對象使用,傳入兩個參數,回頭看less 類的
模闆實作:
即實作了operator() 函數,左操作數小于右操作數時傳回為真。
我們也可以在定義的時候傳遞第三個參數,如map< int, string, greater<int> > mapTest; 則插入時按key 值從大到小排序(less,
greater 都是STL内置的類,裡面實作了operator() 函數),甚至也可以自己實作一個類傳遞進去,如下面例程所示:
輸出為:
3 cccc
2 bbbb
1 aaaa
MyGreater 類并不是以模闆實作,隻是比較key 值為int 類型的大小。
四、函數對象與算法
在STL一些算法中可以傳入函數指針,實作自定義比較邏輯或者計算,同樣地這些函數也可以使用函數對象來代替,直接看例程再稍
作分析:
1 2 3 4 5
6 7 8 9 10
2
回顧for_each 的源碼,其中有這樣一句: _Func(*_ChkFirst); 也就是将周遊得到的元素當作參數傳入函數。
上面程式使用了函數對象,實際上可以這樣了解 PrintObj()(*_ChkFirst); 即 PrintObj() 是一個匿名的函數對象,傳入參
數,調用了operator() 函數進行列印輸出。使用函數對象的好處是比較靈活,比如直接使用函數Add3,那麼隻能将元素加3,而
使用函數對象Addobj(x), 想讓元素加上多少就傳遞給Addobj類,構造一個對象即可,因為它可以儲存一種狀态(類成員)。
count_if 中的 GreaterObj(3) 就類似了,将周遊的元素當作參數傳遞給operator(), 即若元素比3大則傳回為真。
五、STL内置的函數對象類

參考:
C++ primer 第四版
Effective C++ 3rd
C++程式設計規範