天天看點

【C++】【lambda】lambda函數介紹和個人了解(2)——lambda與仿函數

本來是打算11月末的時候寫這篇文章,結果一直拖拖拖拖拖啊啊啊啊啊事多啊事多!ok這是對lambda的分析的第二篇,第三篇準備給大家帶來一些“文法甜點”,不過實在是不知道什麼時候能夠寫完=。=到時候再說

好點的程式設計語言一般都有好的庫支援,c++也不例外。c++語言在标準程式庫stl中向使用者提供了一些基本的資料結構及一些基本的算法等。在c++11之前,我們在使用stl算法時,通常會用到一個特殊的對象,一般來說,我們稱之為函數對象,或者仿函數(functor)。仿函數簡單地說,就是重定義了成員函數operator()的一種自定義類型對象。這樣的對象有個特點,就是其使用在代碼層面感覺跟函數的使用并無二樣,但究其本質卻并非函數。這裡有一個簡單的仿函數的例子(其實仿函數并特性不是c++11的特性,因為目前不支援c++11的線上評測系統poj目前可以編譯仿函數,這個例子就成功的ac了poj的測試題目poj1000)。

         在示例中,class

_functor的operator()被重載,是以,在調用該函數的時候,我們看到跟函數調用一樣的形式,隻不過在這裡的plus不再是函數名稱,而是對象名稱。

當然,既然仿函數是披着函數的對象,那麼就可以像處理一般的對象一樣,可以對對象的部分成員進行初始化。注意,其實在這裡,因為這個仿函數是一個對象,那麼換句話說,你就可以初始化出來很多原理相似但是結果幾乎是完全不同的仿函數示例。比如說下面的那個例子。

不過,如果我們把這些亂七八糟的皮毛剝去,其實lambda函數的定義和仿函數的構造是極其相似的。回到最開始的例子,我們把自定義類型中的聲明和其中對象的定義,至少從代碼的角度上去看,基本上而這毫無差異。那麼我們所抛棄的那些聲明和定義究竟是lambda函數中的哪個部分呢?不賣關子了,先看一份代碼。

這份代碼是一個計算機場反稅的例子。test1和test2分别是用仿函數和lambda兩種方式來計算扣稅後産品價格。請留意下二者的tax_rate的“捕捉”方式。lambda函數通過書寫時的捕捉清單來捕捉tax_rate變量。仿函數是通過tax_rate初始化類,并且構造出名為test1的一個airportprice類執行個體。而在其他方面,參數的傳遞上,二者保持一緻,一模一樣。在目标值的傳回上也和正常的普通函數毫無差别。因而,實際上,除了文法和實際的書寫,在某種意義上,我們可以認為lambda和仿函數是一個“産物”。換句話說,他們兩個都可以捕捉一些變量作為初始狀态,并接受參數進行運算。

開頭我提到了stl算法中的函數對象,通過上文的描述,我們可以認為函數對象裡的兩個元素:lambda和仿函數是等價的,我們可以人工的——當然,隻要你願意寫多餘的代碼就行——把lambda和仿函數進行互相轉化。當然,如果編譯器已經完美支援c++11的話,完全可以把所有的仿函數啊函數指針神馬的妥妥的換成lambda。為什麼?就地定義,就地書寫,就地使用,友善他人對代碼進行研讀,同時友善自己使用,何樂而不為?