2013-04-15 23 views
1

我是新手對於這個概念,但我搜索的區別和函子的好是他們能夠從建築內部存儲值和初始化這些值是什麼與衆不同的函子但正常的函數也以相同的方式工作,除非它們在函數調用中將所有參數作爲整體進行處理。最大的可能是我錯了,在某些方面,但哪裏是把戲和有關函子的正常功能比較正常功能服用值作爲參數

+3

什麼是蘋果和水果之間的區別? – PlasmaHH

回答

3

核心的區別在於函子定義了一個類型而不是函數。即使是無狀態函子(沒有任何附加數據)也可以利用這一點。例如,考慮使用std::less一個排序算法內:

template <typename Iterator, typename Comparator> 
sort(Iterator begin, Iterator end, Comparator c) { 
... 
    if (c(*begin,*end)) { ... 
... 
} 

調用作爲sort(v.begin(), v.end(), std::less<int>());。當函數被調用時,會創建一個std::less<int>的實例並將其傳遞給模板。因爲它是無狀態的,傳遞函數的代價幾乎沒有。在函數內部,調用c(a,b)被確定爲對c.operator()(a,b)的調用,並且編譯器知道該類型。它可以有效地內聯該調用(在這種情況下足夠簡單)並用單個比較指令代替它。

在另一方面,等效C函數qsort接受一個函數指針(也可以不按值傳遞函數)。在qsort之內,編譯器不知道調用的函數是什麼,並且它不能內聯它,所以它必須爲每個比較執行函數調用。

函子既可以添加額外的信息,稍後可以在調用的地方使用(這對於普通函數來說是不可能的),還可以傳遞額外的信息,比如提供需要調用的信息(同樣的行爲可以獲得,但對性能命中)或其他附加信息(類型可以嵌套的性狀檢查類型/類型定義,信息...)

+0

確實'std :: less'是無狀態的,但並不要求可調用對象是無狀態的。有狀態的對象使用起來有點棘手,因爲不能保證它們應對的位置和頻率。所以一個階段性可調用對象通常會持有一個指向其狀態的指針,而不是直接保持狀態。 –

+0

@PeteBecker:同意,我可能不夠清楚:對於具有狀態的函子,沒有選擇。對於無狀態仿函數,可以作爲類型或函數指針來實現,使用仿函數可以向編譯器提供更多信息,以進一步優化代碼。 –

1

正常功能,獨立或成員的利益,只有它們的參數時,函數被調用將被通過。所以沒有辦法將額外的數據傳遞給函數。

這與函子不同。仿函數是對象的一個​​實例,因此它確實可以存儲傳遞給它的構造函數的數據(在傳遞函數時使用)。

用C++ 11個東西糊塗了一下,如lambda表達式也可以「商店」(未技術上是正確的字),通過使用捕獲值。或者使用std::bind,它允許您在實際調用可調用對象時將值綁定爲參數。