C++11:lambda表達式

這個實現的效果類似於匿名函數,不想C++98/03那樣一個函數所有人都能調用,不公開不必要的接口,提高程序安全性。

首先來寫個最簡單的lambda表達式。

[]{};

對,5個字符就成爲了一個lambda表達式了,雖然並沒卵用,不過至少跨出了一步。這個lambda表達式實際上是精簡後的表達式。不加以精簡的話,原表達式應該像這樣:

[](){};

看起來挺簡單的,我也這麼覺得微笑

解釋下,首先一對方括號代表捕獲列表,含義後面再解釋。然後是一對圓括號,代表lambda函數的參數列表,當參數爲空可省略這對圓括號,就像上面5個字符的lambda表達式這樣。接下來是一對大括號,這個和函數的大括號沒什麼區別了,裏面可以加代碼,可以加return。

下面我們來實現一個lambda表達式,用來計算兩個int數字的和

auto sum = [] (int a, int b) {
	return a+b;
};
這兒爲了方便,使用auto自動生成類型。調用方式也簡單,直接   sum(3,5);   就行了,返回的類型爲自動推導類型。
關於這個類型,目前我知道的,有兩種形式保存,一種是通過函數指針。這種方式只能對捕獲列表,也就是那對中括號爲空的lambda函數進行保存,代碼如下:

#include <iostream>
using namespace std;

using pSum = int (*)(int, int);//C++11新特性,類型重定義,效果與  typedef int (*pSum)(int, int);  完全相同

int main (int argc, char* argv []) {
	pSum sum = [] (int a, int b) {
		return a + b;
	};
	cout << sum (3, 5) << endl;
	return 0;
}
結果吶,對你沒猜錯,就是8。
接下來就是針對捕獲列表不爲空的情況了,下面說下捕獲列表的作用。捕獲列表是在函數中定義lambda表達式時,用於方便獲取局部變量的值或引用。

#include <iostream>
using namespace std;

int main (int argc, char* argv []) {
	int i = 5;
	[&i] () { i = 3; }();
	cout << i << endl;
	return 0;
}
定義lambda後直接調用,直接在lambda函數後面加一對圓括號傳參就行了。這兒我定義了一個變量i,然後通過捕獲列表傳入i的引用,然後對i進行重新賦值。程序運行結果爲3。關於捕獲的引用傳遞與值傳遞的區別是,值傳遞後變量不可更改,引用傳遞後變量可修改。上面我傳的是引用,使用“&i”,值傳遞直接寫個 i 就行了。

這兒可以寫多個引用或值傳遞。如果一次性需要引入所有局部變量,那麼寫個 [&] 代表引用所有,寫個 [=]代表傳遞所有的值。傳值後的變量不可修改,有辦法能加個可修改屬性,如下代碼:

#include <iostream>
using namespace std;

int main (int argc, char* argv []) {
	int i = 5;
	[i] () mutable { i = 3; }();
	cout << i << endl;
	return 0;
}
mutable表示可以修改值傳遞的數據,但不影響函數的局部變量。上面這代碼的程序運行結果還是5。
那麼這樣的lambda表達式如何存儲呢?這得通過std::function。如下代碼演示如何存放包含捕獲的lambda表達式

#include <iostream>
#include <functional>
using namespace std;

int main (int argc, char* argv []) {
	function<int (int, int)> f = [] (int a, int b) { return a + b; };
	cout << f (3, 5) << endl;
	return 0;
}
計算兩個數字之和的lambda表達式,除了通過函數指針外,也可通過function存儲。這兒沒有寫捕獲列表,寫了也能存儲。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章