第十六章 string類和標(biāo)準(zhǔn)模板庫(5)函數(shù)對象

(五)函數(shù)對象

函數(shù)對象,也叫作函數(shù)符functor。函數(shù)符是可以以函數(shù)的方式與()結(jié)合的任意對象,包括函數(shù)名,函數(shù)指針,重載了()運算符的類對象(也就是定義了比如double operator()(double)成員函數(shù)的類)。

前面介紹了for_each()函數(shù),可以使用函數(shù)對象作為第三個參數(shù)來對每個迭代器指向的元素進(jìn)行處理,比如for_each(dice.begin(),dice.end(),Show);其中Show就可以是任意一種形式的函數(shù)對象(函數(shù)符)。第三個參數(shù)可以是常規(guī)函數(shù),也可以是函數(shù)符。實際上,for_each()函數(shù)是一個模板函數(shù),前兩個參數(shù)是迭代器,用以指定相應(yīng)的容器的范圍,通過輸入具體的容器,模板也具體化為相應(yīng)的函數(shù),第三個參數(shù)也是一個模板類型符號,通過輸入函數(shù)符,可以將函數(shù)的信息(返回值以及參數(shù)列表)告訴函數(shù)模板,從而具體化為相應(yīng)的類。

1.函數(shù)符的概念

正如STL定義了容器和迭代器的概念一樣,它也定義了函數(shù)符的概念。

生成器generator是不用參數(shù)就可以調(diào)用的函數(shù)符;一元函數(shù)unary function是只有一個參數(shù)的函數(shù)符;二元函數(shù)binary function是有兩個參數(shù)的函數(shù)符。例如,提供給for_each()函數(shù)的函數(shù)符應(yīng)該是一個一元函數(shù)符,因為它每次只處理容器中的一個元素。

這些概念都有相應(yīng)的改進(jìn)版本(上面的都是概念,前面講過概念,改進(jìn)和模型的關(guān)系),返回bool的一元函數(shù)predicate謂詞返回bool的二元函數(shù)是binary predicate二元謂詞。可以使用類模板將兩個參數(shù)的謂詞函數(shù)轉(zhuǎn)換為一個參數(shù)的謂詞函數(shù),其中一個參數(shù)被用作類的構(gòu)造參數(shù)而隱式傳遞給函數(shù)符,從而可以作為函數(shù)適配器,適應(yīng)不同的參數(shù)類型(就是說使用類模板將binary predicate轉(zhuǎn)換為一個函數(shù)類對象,用我們需要的值構(gòu)造這個類對象,這個值就是原來二元函數(shù)的一個參數(shù),這樣新的類對象可以作為一元函數(shù)符來使用了,調(diào)用的時候再給定第二個參數(shù))。總之,兩個參數(shù)的函數(shù)被轉(zhuǎn)換成了單參數(shù)的函數(shù)對象,因此類函數(shù)符可以作為一個函數(shù)適配器,來將多參數(shù)的函數(shù)轉(zhuǎn)換成單參數(shù)的函數(shù),以適應(yīng)不同的需求。

2.預(yù)定義的函數(shù)符

STL定義了許多基本函數(shù)符,提供這些函數(shù)對象是為了支持將函數(shù)作為參數(shù)的STL函數(shù)。STL在頭文件<functional>中定義了許多函數(shù)模板類,可以支持很多的運算,比如plus<>就是將兩個參數(shù)相加的函數(shù)符,當(dāng)實例化以后,比如plus<double> xx;則xx就像普通的二元函數(shù)那樣使用就可以了。

其他的函數(shù)還有很多,大部分是對算術(shù)運算符的模板化,比如-是minus,*是multiplies,/是divides,>=是greater_equal等等。

3.自適應(yīng)函數(shù)符和函數(shù)適配器

自適應(yīng)函數(shù)符是指攜帶了標(biāo)識參數(shù)類型和返回類型的typedef成員(也即是說我們可以調(diào)用這些成員,從而可以知道函數(shù)模板具體化之后的相應(yīng)的參數(shù)和返回值的類型)。這些成員分別是result_type,first_argument_type和second_argument_type。自適應(yīng)的意思就是可以通過查看來適應(yīng)程序環(huán)境,這種特性被用作將二元函數(shù)轉(zhuǎn)換為一元函數(shù)等場景中,相當(dāng)于函數(shù)的適配,只不過這種適配是自動進(jìn)行的,如binder1st(f2,val)f1;f1(x);就相當(dāng)于先定義了一個函數(shù)對象,將第一個參數(shù)加進(jìn)去,這個函數(shù)對象就可以再調(diào)用第二個參數(shù),總體的作用就像調(diào)用了f2(val,x)的效果。

c++11提供了函數(shù)指針和函數(shù)符的替代品,拉姆達(dá)表達(dá)式。這將在后面討論。


最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

推薦閱讀更多精彩內(nèi)容