C++11 Lambda表達式

Lambda表達式

匿名函數有函數體,但沒有函數名。
匿名函數是很多高級語言都支持的概念,如lisp語言在1958年首先採用匿名函數。正因爲如此,C++11也同樣引入了lambda函數。
在C++11中,你可以在源碼中內聯一個lambda函數,這就使得創建快速的、一次性的函數變得簡單了。

相同類似功能我們也可以使用函數對象或者函數指針實現:函數對象能維護狀態,但語法開銷大,而函數指針語法開銷小,卻沒法保存範圍內的狀態。lambda表達式正是結合了兩者的優點。

聲明Lambda表達式

[capture list] (params list) mutable exception-> return type { function body };
[capture list] (params list) -> return type {function body};  //1
[capture list] (params list) {function body};		//2
[capture list] {function body};		//3
  • capture list:捕獲外部變量列表
  • params list:形參列表
  • mutable指示符:用來說用是否可以修改捕獲的變量
  • exception:異常設定
  • return type:返回類型
  • function body:函數體

標號1. 函數聲明瞭一個const類型的表達式,此聲明不可改變capture list中的捕獲的值。
標號2. 函數省略了返回值,此時如果function body內含有return語句,則按return語句返回類型決定返回值類型,若無則返回值爲void類型。
標號3. 函數無參數列表,意味無參函數。

簡單的例子

在C++中我們對STL庫中的sort()運用十分頻繁,接下來就是關於他的一個例子:

//省略細節
bool compare(int a,int b){
	return a<b;
}
{
	vector<int> vec{1,0,9,5,3,3,7,8,2};
	sort(vec.begin(),vec.end(),compare);
	//在C++11之前,我們使用STL的sort函數,可以提供一個謂詞函數來爲sort改變其排序判斷標準
}

接下來是lambda表達式的形式:

{	
	vector<int> vec{1,0,9,5,3,3,7,8,2};
	sort(lbvec.begin(), lbvec.end(), [](int a, int b) -> bool { return a < b; });  
	 // Lambda表達式
}

lambda不僅提高了代碼可讀性,且在例子中,這一個提供判斷依據的函數是隻需調用一次,在這時,lambda表達式就顯示出它的“即用即扔”的特點,很適合這種不需要重複調用且運用區域單一的情景(而不是去多寫一個compare的函數)。

捕獲外部變量

Lambda表達式可以捕獲外面變量,但需要我們提供一個謂詞函數([capture list]在聲明表達式最前)
類似參數傳遞方式:值傳遞、引入傳遞、指針傳遞。
在Lambda表達式中,外部變量捕獲方式也類似:值捕獲、引用捕獲、隱式捕獲

值捕獲

    int a = 123;
    auto f = [a] { cout << a << endl; }; 
    f(); // 輸出:123
    a = 321;
    f(); // 輸出:123

值捕獲和參數傳遞中的值傳遞類似,被捕獲的值在Lambda表達式創建時通過值拷貝的方式傳入,因此Lambda表達式函數體中不能修改該外部變量的值;同樣,函數體外對於值的修改也不會改變被捕獲的值。

引用捕獲

    int a = 123;
    auto f = [&a] { cout << a << endl; }; 
    a = 321;
    f(); // 輸出:321

引用捕獲的變量使用的實際上就是該引用所綁定的對象,因此引用對象的改變會改變函數體內對該對象的引用的值。

隱式捕獲

隱式捕獲有兩種方式,分別是
[=]:以值補獲的方式捕獲外部所有變量
[&]:表示以引用捕獲的方式捕獲外部所有變量

	int a = 123 ,b=321;
    auto df = [=] { cout << a << b << endl; };    // 值捕獲
    auto rf = [&] { cout << a << b << endl; };    // 引用捕獲

其他捕獲方式

C++11Lambda表達式捕獲外部變量形式
[ ] 不捕獲任何變量(無參函數)
[變量1,&變量2, …] 值(引用)形式捕獲指定的多個外部變量
[this] 值捕獲this指針
[=, &x] 變量x以引用形式捕獲,其餘變量以傳值形式捕獲

Lambda表達式的參數

  • 參數列表中不能有默認參數
  • 不支持可變參數
  • 所有參數必須有參數名
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章