STL程式設計實踐七:儘量定義class形式的Function Object (轉)

gugu99發表於2008-04-28
STL程式設計實踐七:儘量定義class形式的Function Object (轉)[@more@]

STL設計實踐七:儘量定義class形式的Function :namespace prefix = o ns = "urn:schemas--com::office" />

袁小凱

華南理工大學研究所北區研發二部

E –

 

前言 

在使用STL進行程式設計時,你會經常用到Function Object,尤其是在寫一個泛型演算法並充許把行為引數化時。Function Object簡單點講分兩種:1.指標(最簡單的Function Object)。2.class形式的Function Object。

1. 函式指標(最簡單的Function Object)

函式指標指向一個函式,指向的函式一般為全域性函式。透過函指標可以使行為引數化。

int a[5]={1,2,3,4,5};

vector obj(a,a+5);

find_if(a,a+5,equalcmp);  //找出第一個等於5的元素

這裡的equalcmp是一個函式指標,它指向一個全域性函式equalcmp。

bool equalcmp (int x){return x==5;}

這裡透過傳入函式指標使得我們可以使演算法find_if按照我們定義的行為進行查詢。

2. class 形式的Function Object

簡單點說就是定義了operator () 成員函式的類。這樣的類可以像函式一樣進行,如果說 equalcmp 就是這樣一個類,ecfo是其一個,則可進行如下函式呼叫動作:

ecfo();  //類似無參的函式呼叫,當然也以有引數。

還拿前面的例子來說,把equal_5定義成class形式的Funtion Object,如下:

struct equalcmp

{

  equalcmp(int x=5):data(x){}

bool operator () (int x){return data==x;}

  int data;

};

定義了equalcmp後我們可以利用它來進行find_if查詢。

find_if(a,a+5,equalcmp(5));  //找出第一個等於5的元素

它的行為個前面的一樣,注意equalcmp(5)的形式,它是用於產生一個臨時的equalcmp物件,得以呼叫operator ()成員函式。

3.兩者的比較

函式指標形式的functor(Function Object的另一種叫法)好像不夠靈活,因為如果equalcmp不找等於5的元素了,換找4,它不能用了。你是改那,還是重寫一個。哈哈!但class形式的functor(寫起來方便多了^_^)可以減少這種無聊的重複勞動。換找4!,不就是找4嗎,沒問題。

find_if(a,a+5,equalcmp(4));

搞定!簡單,方便,好用。如果用函式指標來實現這種功能可有些困難,因為無法區域性狀態,如果要實現可能需要全域性變數。如果需要多個這樣的functor會需要多個全域性變數,不是儘量不要用全域性變數嗎?一些專家的忠告。但是還是有些人會固執認為類functor會的問題,因為要構造和析構。它們在尋求一種解決方法,他們可能找到了一種如下的方法:

  template

bool equalcmp(int x)

{  return x==N; }

find_if(a,a+5,equalcmp<4>(4));//找4,VC(X),G++2.91.57(X),CB(O)

請問這種方法能行嗎?你試過嗎?如果沒試試吧!這在某些上可以,有些不行。但絕對可以這樣呼叫equalcmp<4>(4);如果曾經這樣呼叫過再這樣使用find_if(a,a+5,equalcmp<4>(4))是可以的。可能是編譯器產生Function Template實體時機的問題。

假設這樣做可以,但是這不夠一般化。你可使用類的形式寫出更一般化的functor,可以滿足所有的資料型別。

template

struct equalcmp

{

equalcmp(T x=5):data(x){}

bool operator () (T x){return data==x;}

T data;

};

  find_if(a,a+5,equalcmp(4));

現在equalcmp可以使用任意資料型別,這一下使用函式指標可沒法完成了吧!因為你寫不出這樣的函式來讓它指。哈哈!鬆口氣先,再喝口水。還有函式指標沒法用Adaptable Function Object,因為它無進行巢狀定義資料型別。太多函式指標無法完成動作了。那是不是函式指標就沒有用了呢?不是,當你已經有了一個函式可用,那你就可以用函式指標,而不用重寫一個class形式的functor。還有函式指標也可透過Function Object Adaptor轉換成Adaptable Function Object。就說這麼多吧!

總之!如果你沒有現成的函式可用,請定義class形式的Function Object。

後語:

  該文是我個人的學習總結,如果有什麼錯誤請大家指正。

 


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10748419/viewspace-1003097/,如需轉載,請註明出處,否則將追究法律責任。

相關文章