STL與泛型程式設計《十四》 仿函式介紹

2021-07-10 19:35:30 字數 3114 閱讀 4783

仿函式(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...