選擇自 sevecol 的 blog
我們知道在stl中函式物件發揮著很大作用:
find_if(coll.begin(),coll.end(),bind2nd(greater(),42));
這裡bind2nd就是乙個函式物件,他提供了operator()的處理,是的我們可以象呼叫函式一樣操作,這也就是他名字的由來.
find_if的第三個引數我們也可以使用傳遞函式指標,比如
bool mygreater(int t)
find_if(coll.begin(),coll.end(),mygreater);這樣是完全合法的.
但是問題來了,如果我們想使用成員函式該怎麼辦?
class a
};我怎麼對vector中的元素執行這個greater?直接使用是不行了,只有採用的別的策略.
在設計模式中有一種介面卡模式,目的就是解決兩種介面不相容的問提,我們再回過頭看看我們上面的問題,我們正是遇到這種不相容的問題.摸板函式需要的型別和我們的準備提供的操作介面不相容.(成員函式指標多了乙個this,所以呼叫上和一般函式有所不同).
當然你也可以多做乙個版本的find_if來適應成員函式,下面的這個函式
template
inline _init mem_find_if(_init _first, _init _last, bool (_type::*_p)())
現在就可以直接
mem_find_if(coll.begin(),coll.end(),&a::greater);
但這種方法有點象補漏洞的感覺,有沒有更加優雅的,不用在在最基礎的地方新增函式的方式呢?
這裡就是stl中的介面卡的乙個作用了,這裡要談到的介面卡是mem_fun_ref,將成員函式介面轉化成乙個函式物件.我們先來看看他的使用:
find_if(coll.begin(),coll.end(),mem_fun_ref(&a::greater));
接下來讓我們仔細看看這個介面卡:
templateinline
mem_fun_ref_t<_result, _ty> mem_fun_ref(_result (_ty::*_pm)())
這個函式返回乙個mem_fun_ref_t<_result, _ty>物件(這個函式物件就是適配兩個介面的物件),呼叫的是mem_fun_ref_t<_result, _ty>(_pm))這個建構函式.在這裡_result是我們成員函式的返回值,_ty是我們的類的型別,_pm就是我們打算呼叫的成員函式的指標.
我們再來看看我們真正傳遞給find_if的函式物件
template
class mem_fun_ref_t: public unary_function<_ty, _result>
_result operator()(_ty& _left) const
private:
_result (_ty::*_pmemfun)(); // the member function pointer};
這裡最需要關注的就是operator(),這個函式有乙個引數_ty& _left,這裡的_ty就是我們上面談到的類的型別,這個operator()滿足了find_if對於操作的要求.這個operator()的實質就是對於_left呼叫pmemfun,而這個pmemfun在建構函式中初始化為我們傳遞的函式指標.
這樣就完成我們對於成員函式的呼叫了.這個介面卡產生乙個函式物件將原本不相容的兩個介面(find_if所需要的型別和成員函式型別)完美的相容了.
STL介面卡 函式介面卡
有時候需要對內建函式物件返回值進行進一步的簡單計算,或者填上多餘的引數,不能直接代入演算法。函式介面卡實現了這一功能,函式介面卡是將一種函式物件轉化為另一種符合要求的函式物件。函式介面卡可以分為4個大類 繫結介面卡 組合介面卡 指標函式介面卡和成員函式介面卡。需求 在遍歷容器的時候,將容器中的值全部...
STL中函式介面卡
首先為什麼要用函式介面卡?stl中的函式介面卡分類 1 繫結介面卡用法 將乙個運算元繫結到給定值而將二元函式物件轉換為一元函式物件。bind2nd 將給定值繫結到二元函式物件的第二個實參 bind1st 將給定值繫結到二元函式物件的第乙個引數 示例程式如下 include include inclu...
STL 介面卡實現
函式介面轉函式物件介面的介面卡 內部呼叫引數為指標型別 template class const mem fun t public unary function ret operator const tp p const private ret tp m f const const函式介面轉函式物件...