Lambda 表達式是 C++11 中最重要的新特性之一。類似匿名函數,當需要一個函數但是又不想費力去命名時使用。這樣的場景其實有很多,所以匿名函數幾乎是現代編程語言的標配。 Lambda 表達式基礎 Lambda 表達式的基本語法如下: [捕獲列表](參數列表) mutable(可選)異常屬性 -... ...
Lambda 表達式是 C++11 中最重要的新特性之一。類似匿名函數,當需要一個函數但是又不想費力去命名時使用。
這樣的場景其實有很多,所以匿名函數幾乎是現代編程語言的標配。
Lambda 表達式基礎
Lambda 表達式的基本語法如下:
[捕獲列表](參數列表) mutable(可選)異常屬性 -> 返回類型 { |
捕獲列表,可以理解為參數的一種類型。
lambda 表達式內部函數體在預設情況下是不能夠使用函數體外部的變數的,這時候捕獲列表可以起到傳遞外部數據的作用。
根據傳遞的行為,捕獲列表也分為以下幾種:
1. 值捕獲
值捕獲的前提是變數可以拷貝,被捕獲的變數在 lambda 表達式被創建時拷貝,而非調用時才拷貝:
void
learn_lambda_func_1() { |
2. 引用捕獲
引用捕獲保存的是引用,值會發生變化:
void
learn_lambda_func_2() { |
3. 隱式捕獲
手動書寫捕獲列表有時候是非常複雜的,這種機械性的工作可以交給編譯器來處理。
可以在捕獲列表中寫一個 & 或 = 向編譯器聲明採用 引用捕獲或者值捕獲。
捕獲列表的最常用的四種形式可以是:
[] 空捕獲列表
[name1, name2, ...] 捕獲一系列變數
[&] 引用捕獲, 讓編譯器自行推導捕獲列表
[=] 值捕獲, 讓編譯器執行推導應用列表
4. 表達式捕獲(C++14)
這部分內容需要瞭解後面馬上要提到的右值引用以及智能指針
上面提到的值捕獲、引用捕獲都是已經在外層作用域聲明的變數,因此這些捕獲方式捕獲的均為左值,而不能捕獲右值。
C++14允許捕獲的成員用任意的表達式進行初始化。
被聲明的捕獲變數類型會根據表達式進行判斷,判斷方式與使用auto 本質上是相同的:
#include
<iostream> |
在上面的代碼中, important 是一個獨占指針,是不能夠被捕獲到的,這時候我們需要將其轉移為右值,在表達式中初始化。
泛型 Lambda(C++14)
Lambda 表達式並不是普通函數,所以 Lambda 表達式並不能夠模板化。
這就為我們造成了一定程度上的麻煩:參數表不能夠泛化,必須明確參數表類型。
從 C++14 開始,Lambda 函數的形式參數可以使用 auto 關鍵字來產生意義上的泛型:
auto
add = [](auto
x, auto
y) { |