c++11終於知道要在語言中加入匿名函式了。匿名函式在很多時候可以為編碼提供便利,這在下文會提到。很多語言中的匿名函式,如c++,都是用lambda表示式實現的。lambda表示式又稱為lambda函式。我在下文中稱之為lambda函式。
為了明白lambda函式的用處,請務必先搞明白c++中的自動型別推斷:
我們可以這樣定義乙個lambda函式:
[cpp]view plain
copy
#include
using
namespace
std;
intmain()
; func(); // now call the function
}
其中func就是乙個lambda函式。我們使用auto來自動獲取func的型別,這個非常重要。定義好lambda函式之後,就可以當這場函式來使用了。
其中 [ ] 表示接下來開始定義lambda函式,中括號中間有可能還會填引數,這在後面介紹。之後的()填寫的是lambda函式的引數列表{}中間就是函式體了。
正常情況下,只要函式體中所有return都是同乙個型別的話,編譯器就會自行判斷函式的返回型別。也可以顯示地指定lambda函式的返回型別。這個需要用到函式返回值後置的功能,比如這個例子:
[cpp]view plain
copy
() ->
int
所以總的來說lambda函式的形式就是:
[cpp]view plain
copy
[captures] (params) -> ret
假設你設計了乙個位址簿的類。現在你要提供函式查詢這個位址簿,可能根據姓名查詢,可能根據位址查詢,還有可能兩者結合。要是你為這些情況都寫個函式,那麼你一定就跪了。所以你應該提供乙個介面,能方便地讓使用者自定義自己的查詢方式。在這裡可以使用lambda函式來實現這個功能。
[cpp]view plain
copy
#include
#include
class
addressbook
} return
results;
} private
: std::vector_addresses;
};
從上面**可以看到,findmatchingaddressses函式提供的引數是func型別,這是乙個泛型型別。在使用過程中應該傳入乙個函式,然後分別對位址簿中每乙個entry執行這個函式,如果返回值為真那麼表明這個entry符合使用者的篩選要求,那麼就應該放入結果當中。那麼這個func型別的引數如何傳入呢?
[cpp]view plain
copy
addressbook global_address_book;
vectorfindaddressesfromorgs ()
);
}
可以看到,我們在呼叫函式的時候直接定義了乙個lambda函式。引數型別是
[cpp]view plain
copy
const
string& addr
返回值是bool型別。
如果使用者要使用不同的方式查詢的話,只要定義不同的lambda函式就可以了。
在上述例子中,lambda函式使用的都是函式體的引數和它內部的資訊,並沒有使用外部資訊。我們設想這樣的乙個場景,我們從鍵盤讀入乙個名字,然後用lambda函式定義乙個匿名函式,在位址簿中查詢有沒有相同名字的人。那麼這個lambda函式勢必就要能使用外部block中的變數,所以我們就得使用變數擷取功能(variable capture)。
[cpp]view plain
copy
// read in the name from a user, which we want to search
string name;
cin>> name;
return
global_address_book.findmatchingaddresses(
// notice that the lambda function uses the the variable 'name'
[&] (const
string& addr)
);
從上述**看出,我們的lambda函式已經能使用外部作用域中的變數name了。這個lambda函式乙個最大的區別是中間加入了&符號。這就告訴了編譯器,要進行變數擷取。這樣lambda函式體就可以使用外部變數。如果不加入任何符號,編譯器就不會進行變數擷取。
下面是各種變數擷取的選項:
lambda函式的引入為stl的使用提供了極大的方便。比如下面這個例子,當你想便利乙個vector的時候,原來你得這麼寫:
[cpp]view plain
copy
vector<
int> v;
v.push_back( 1 );
v.push_back( 2 );
//...
for( auto itr = v.begin(), end = v.end(); itr != end; itr++ )
現在有了lambda函式你就可以這麼寫
[cpp]view plain
copy
vector<
int> v;
v.push_back( 1 );
v.push_back( 2 );
//...
for_each( v.begin(), v.end(), (int
val)
);
而且這麼寫了之後執行效率反而提高了。因為編譯器有可能使用」迴圈展開「來加速執行過程(計算機系統結構課程中學的)。
這個ppt詳細介紹了如何使用lambda表示式和stl
**:
c 11新特性 lambda函式
lambda歷史悠久,在數理邏輯和電腦科學領域,lambda被用來表示一種匿名函式這種匿名函式代表了一種 演算 lambda calculus 但是在c 領域直到c 11才引入lambda表示式,本文先打算從lambda函式入手 後續會繼續從lambda與仿函式 lambda基礎應用 lambda的...
C 11新特性 Lambda函式(匿名函式)
宣告 本文參考了alex allain的文章 加入了自己的理解,不是簡單的翻譯 c 11終於知道要在語言中加入匿名函式了。匿名函式在很多時候可以為編碼提供便利,這在下文會提到。很多語言中的匿名函式,如c 都是用lambda表示式實現的。lambda表示式又稱為lambda函式。我在下文中稱之為lam...
C 11新特性 Lambda函式(匿名函式)
宣告 本文參考了alex allain的文章 加入了自己的理解,不是簡單的翻譯 c 11終於知道要在語言中加入匿名函式了。匿名函式在很多時候可以為編碼提供便利,這在下文會提到。很多語言中的匿名函式,如c 都是用lambda表示式實現的。lambda表示式又稱為lambda函式。我在下文中稱之為lam...