C++回呼函數(callback)與仿函數(functor)的異同

來源:互聯網
上載者:User
C++回呼函數(callback)與仿函數(functor)的異同

許式偉 (著作權聲明)
2007-3-3

回呼函數(callback)與仿函數(functor)很多時候從用途上來看很相似,以致於我們經常將它們相提並論。例如:

inline bool compare(int a, int b)
{
   return a > b;
}
 
struct comparer {
  bool operator()(int a, int b) const {
     return a > b;
  }
};
 
void main()
{
   std::vector<int> vec, vec2;
   std::sort(vec.begin(), vec.end(), compare);
   std::sort(vec2.begin(), vec2.end(), comparer());
}

仿函數(functor)之所以稱為仿函數,是因為這是一種利用某些類對象支援operator()的特性,來達到類比函數調用效果的技術。

如果這裡vec, vec2這兩個vector的內容一樣,那麼從執行結果看,使用回呼函數compare與使用仿函數comparer是一樣的。

那麼,我們應該用回調,還是用仿函數?

很多人都說用仿函數吧,回呼函數是醜陋的,代碼不太象C++風格。

但其實問題的本質不是在代碼風格上,仿函數與回呼函數各有利弊,不能一概而論。

仿函數(functor)的優點

我的建議是,如果可以用仿函數實現,那麼你應該用仿函數,而不要用回調。原因在於: 

  • 仿函數可以不帶痕迹地傳遞上下文參數。而回調技術通常使用一個額外的void*參數傳遞。這也是多數人認為回調技術醜陋的原因。
  • 更好的效能。

仿函數技術可以獲得更好的效能,這點直觀來講比較難以理解。你可能說,回呼函數申明為inline了,怎麼會效能比仿函數差?我們這裡來分析下。我們假設某個函數func(例如上面的std::sort)調用中傳遞了一個回呼函數(如上面的compare),那麼可以分為兩種情況:

  • func是內嵌函式,並且比較簡單,func調用最終被展開了,那麼其中對回呼函數的調用也成為一普通函數調用(而不是通過函數指標的間接調用),並且如果這個回呼函數如果簡單,那麼也可能同時被展開。在這種情形下,回呼函數與仿函數效能相同。
  • func是非內嵌函式,或者比較複雜而無法展開(例如上面的std::sort,我們知道它是快速排序,函數因為存在遞迴而無法展開)。此時回呼函數作為一個函數指標傳入,其代碼亦無法展開。而仿函數則不同。雖然func本身複雜不能展開,但是func函數中對仿函數的調用是編譯器編譯期間就可以確定並進行inline展開的。因此在這種情形下,仿函數比之於回呼函數,有著更好的效能。並且,這種效能優勢有時是一種無可比擬的優勢(對於std::sort就是如此,因為元素比較的次數非常巨大,是否可以進行內聯展開導致了一種雪崩效應)。
仿函數(functor)不能做的?

話又說回來了,仿函數並不能完全取代回呼函數所有的應用場合。例如,我在std::AutoFreeAlloc中使用了回呼函數,而不是仿函數,這是因為AutoFreeAlloc要容納異質的解構函式,而不是只支援某一種類的析構。這和模板(template)不能處理在同一個容器中支援異質類型,是一個道理。

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.