https://msdn.microsoft.com/zh-cn/library/dd293608.aspx
lambda表達式是C++11的標准。如果用的是g++,記得加參數。
lambda表達式在其所在的位置上定義了一個匿名函數對象。
先給個例子:
#include <algorithm> #include <cmath> void abssort (float *x, unsigned n) { std::sort (x, x + n, //Lambda 表達式 [](float a, float b) { return (std::abs(a) <std::abs(b)); } ); }
以下時來自微軟官網的解釋:
1、捕獲子句(lambda表達式從此處開始,也叫做lambda-introducer。)(14標准)
捕獲子句指定了哪些變量可以被捕獲,以及捕獲的形式(值還是引用)。捕獲的是lambda表達式所在的封閉作用域中。
如果[]裡為空,表示任何變量都不會傳遞給lambda表達式。
[=]表示默認按值傳遞,[&]表示默認按引用傳遞。[var]:var是變量名,前面可以添加&前綴,表示var變量按引用傳遞。
[&total, factor] //total 按引用傳進來,factor則是按值傳遞 [&, factor] //默認引用 [=, &total] //默認傳值 [=, total] //出錯,原因:重復。默認按值,total也是按值,此時可以將total省略掉 [=, this] //同樣的原因出錯,有人可能會認為this是指針。但要記住指針和引用不同,指針本身同樣是按值傳遞的。
C++14標准中還允許在捕獲子句中創建並初始化新的變量,如:
pNums = make_unique<vector<int>>(nums); auto a = [ptr = move(pNums)]() { //use ptr };
2、參數列表(可選,也叫做lambda聲明符(lambda declarator)
接收輸入參數,如果參數類型是通用的,可以選擇auto關鍵詞作為參數類型(模版)。
auto y = [] (auto first, auto second) { return first + second; };
因為lambda表達式可以作為右值賦值給變量,所以也可以作為參數傳遞給lambda的參數列表。3、mutable 選項(可選)
加上mutable後,lambda表達式體內的語句可以修改按值捕獲的變量。
4、異常選項(可選)
加上throw()表示lambda表達式不拋出任何異常(別搞反了),下面的代碼會出錯的
//windows 環境下使用cl編譯器
//compile with:/W4 /EHsc
int main() //C4297 expected { [] () throw {throw 5;}(); }
5、尾部返回類型(trailing-return-type) (可選)
一般來講lambda表達式的返回值都可以由編譯器自動猜測除非你指明了尾部返回類型。
6 lambda 本體
int main() { int m = 0; int n = 0; [&, n] (int a) mutable { m =++n + a; } (4); cout << m << endl <<n <<endl;
}
output:
5
0
4是通過參數列表裡的a傳進。默認為引用所以m的修改會影響外面的值。雖然加了mutable,但是n修改的只是副本,如果不加mutable,會報錯。