仿函式(functor)就是定義了operator()的一種型別(或例項化的物件),可以如下使用
functionobjecttype fo;
...fo(...) //並不是使用函式fo(),而是呼叫fo的operator()函式
明顯其和函式的很像,只不過函式是在函式體內實現,而其實在operator()裡實現相關功能,偽**如下
class functionobjecttype
}
顯然仿函式更複雜,那麼必然會有其優勢的
1. 仿函式更靈活,因為其是一種型別,可以擁有狀態
2.每個仿函式都是一種型別,此可以把它當作tmpelate的引數進行傳遞,這個是普通函式做不到的,從而指定某種行為模式,還有乙個好處就是容器的型別也會因仿函式的不同而不同
3. 仿函式比一般函式指標快(深表懷疑!!!有時間試試)
見如下例子
#include
#include
#include
#include
#include
using
namespace
std;
class person
};class personsort
};int main(void)
/*輸出:wang er
wang san
zhao si
*/
關於仿函式的operator()返回值?這個其實是看具體要求的,你需要用到的仿函式的地方,且帶入演算法時不需要帶入引數,其中仿函式的operator()的引數是演算法自動把其區間的元素值帶進去進行運算的。
見下例子
#include
#include
#include
#include
using
namespace
std;
class intsequence
intoperator() () //返回值為什麼得是int而不是void,因為後面的generate_n()裡的引數這樣要求的
};template
inline
void print_elements(const t& col, const
char* str=" ")
int main(void)
下是generate_n的**,因此可以看出
template
_outputiterator
generate_n(_outputiterator __first, _size __n, _generator __gen)
仿函式是pass by value(傳值),而不是pass by reference(引用),因此演算法並不會改變隨引數而來的仿函式的狀態。其實演算法當然是可以改變仿函式的狀態,但由於傳遞的只是乙個副本,改變的也只是乙個副本。
如要改變仿函式的狀態,有兩種方法
1. 指明pass by reference傳遞仿函式
2. for_each的回返值
呼叫演算法時指明仿函式型別是個reference型別
#include
#include
#include
#include
using
namespace
std;
class intsequence
intoperator() () //返回值為什麼得是int而不是void,因為後面的generate_n()裡的引數這樣要求的
};template
inline
void print_elements(const t& col, const
char* str=" ")
int main(void)
例子
#include
#include
#include
#include
using
namespace
std;
class meanvalue
meanvalue() : _num(0), _sum(0) {}
void
operator() (int elem) //返回值為什麼得是int而不是void,因為後面的generate_n()裡的引數這樣要求的
double value()
};template
inline
void print_elements(const t& col, const
char* str=" ")
int main(void)
所謂判斷式就是返回布林值的乙個函式或仿函式,見下例子
#include
#include
#include
#include
using
namespace
std;
class nth
bool
operator() (int)
};//改仿函式就是移除第nth個元素
int main(void)
奇怪?按道理應該只移除乙個3,可是卻移除了3和6,為什麼?
先看看remove_if的源**,見下
這個演算法使用find_if()來搜尋被移除的第乙個元素,然而,接下來它使用傳進來的判斷式op的副本去處理剩餘的元素,這時原始狀態下的nth再一次被使用,因而會移除剩餘的第3個元素,也就是整體的第6個元素。
還有,見圖把,解釋不清楚了。總的來說就是你的仿函式設計的不合理,不應該改變判斷式的狀態。
仿函式就是寫乙個class,然後為這個class過載乙個operator()操作就可以了,至於operator() 函式的返回值及引數值你就看演算法的需要而定了。
泛型仿函式三
成員函式指標 有些c 編譯器廠商定義出一種新型別,讓你可以通過以下語法儲存operator.操作結果 void closure geronimoswork geronimo.pactivity geronimoswork template class memfunhandler public fun...
STL原始碼解析 STL 與 泛型程式設計
物件導向程式設計與泛型程式設計template typename t class vector int ar 6 vector int,allocator int vec ar,ar 6 cout count if vec.begin vec.end notl bind2nd less int 6 ...
泛型程式設計與STL 讀書筆記
include stdafx.h include include include include include include using namespace std class even int tmain int argc,tchar argv include stdafx.h include...