lamda表達式是C++11中的新特征,說白了就是匿名函數。
lambda表達式的具體形式如下:
[capture](parameters)->return-type{body}
其中, capture是需要用到的外部變量, parameters是函數參數,return-type是返回的類型(可省略),body是函數體。
來個最簡單的:
[](){};
”[]"表示不需要使用外部變量,”()"表示形參列表為空,"{}"表示空函數,什么都不干。
再舉一個例子。
在STL中有一個排序函數std::sort,如果現在我們要用它來按降序排列一個數組arr,則可自定義一個比較函數cmp,並把它傳給sort函數,如下
bool cmp(int a, int b) { return a > b; } std::sort(arr, arr + len, cmp);
若果使用lamda表達式,則可改寫成如下
std::sort(arr, arr + len, [](int a, int b) { return a > b; });
"[]"表明沒有用到外部變量,如果我們要用到外部變量,則要對"[]"進行修改,如下代碼
int n = 10; [](int a) {return a + n;}; // 報錯,提示變量n不能在lamda體中調用,除非其在捕獲列表中
捕獲列表是指"[]",因此我們在"[]"中加上n即可。如下
int n = 10; [n](int a) {return a + n;}; // 正確
"[n]"說明n是以傳值的方式傳到lamda體中,傳值和傳引用的差別請自行百度。捕獲列表可按如下規則傳入
- [] 什么也沒有捕獲
- [a, &b] 按值捕獲a,按引用捕獲b
- [&] 按引用捕獲任何用到的外部變量
- [=] 按值捕獲任何用到的外部變量
- [a, &] 按值捕獲a, 其它的變量按引用捕獲
- [&b, =] 按引用捕獲b,其它的變量按值捕獲
- [this] 按值捕獲this指針
注意: 假如我們想修改按值傳進來的形參,將會發生錯誤,因為按值捕獲的對象不能被修改,如下代碼
int n = 10; [n](int a) { n += a; // 報錯,提示不允許修改n的值 return n; };
這時我們需要假如一個mutable,如下
int n = 10; [n](int a)mutable { n += a; // 正確 return n; };
關於返回值類型,可由以下規則推導出來
- 如果body僅包含單一的return語句,那么返回值類型是返回表達式的類型(在此隱式轉換之后的類型:右值到左值、數組與指針、函數到指針)
- 否則,返回類型是void
譬如我們上面std::sort()的這個例子,lamda表達式是
[](int a, int b) {return a > b;};
a > b 這個表達式返回的類型是bool,因此這個lamda表達式返回類型是bool。
最后一個例子,我們可以把lamda表達式進行賦值,還是利用std::sort()這個例子。我們可以把cmp函數寫成如下
std::function<bool(int, int)> cmp = [](int a, int b) {return a > b;}; //std::function包含在頭文件functional中,具體用法請自行百度
這樣做的好處是可以多次利用lamda表達式。當然,我們可以指定其返回類型為auto,來讓其自行判斷。
auto cmp = [](int a, int b) {return a > b;};
lamda表達式的簡單介紹到此結束。文章若有錯漏之處,請提出,多謝。
參考:
Lambda函數(C++11 起):http://zh.cppreference.com/w/cpp/language/lambda 代碼簡潔之道:C++ 11 之auto+ for_each + lamda表達式:http://www.itnose.net/detail/6090413.html