lambda 表達式(匿名函數)的具體應用和使用場景
lambda
表達式的定義形式如下:
[capture list] (parameter list) -> reurn type
{
function body
}
其中:
capture list:捕獲列表,指 lambda 表達式所在函數中定義的局部變量的列表,通常為空,但如果函數體中用到了 lambda 表達式所在函數的局部變量,必須捕獲該變量,即將此變量寫在捕獲列表中。捕獲方式分為:引用捕獲方式 [&]、值捕獲方式 [=]。
return type、parameter list、function body:分別表示返回值類型、參數列表、函數體,和普通函數一樣。
舉例:
lambda 表達式常搭配排序算法使用。
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main()
{
vector<int> arr = {3, 4, 76, 12, 54, 90, 34};
sort(arr.begin(), arr.end(), [](int a, int b) { return a > b; }); // 降序排序
for (auto a : arr)
{
cout << a << " ";
}
return 0;
}
/*
運行結果:90 76 54 34 12 4 3
*/
lambda 表達式是一個可調度的代碼單元,可以視為一個未命名的內部函數
lambda 函數是一個函數對象,編譯器在編譯時會生成一個 lambda 對象的類,然后再生成一個該命令未命名的對象
lambda 的形式如下:
[捕獲列表] (參數列表) -> 返回類型 { 函數部分 }
[capture list] (parameter list) -> return type { function body }
capture list 捕獲列表是 lambda 函數所定義的函數的局部變量列表, 通常為空
一個 lambda 只有在其捕獲列表中捕獲一個所在函數中的局部變量,才能在函數體中使用該變量。
捕獲列表只用於局部非 static 變量。 lambda 可以直接使用局部變量 static 變量 和在它所在函數之外的聲明的名字。
捕獲列表的變量可以分為 值 或 引用傳遞。
值傳遞: lambda 捕獲的變量在 lambda 函數 創建 就發生了拷貝而非調用時。
隱式捕獲:
編譯器可以根據 lambda 中的代碼推導使用的變量,為指示編譯器推斷捕獲列表,應該在捕獲列表中寫一個 & 或 =
& 告知編譯器采用引用傳遞方式
= 告知編譯器采用值傳遞方式
當混合使用時,捕獲列表第一個參數必須是 & 或 = 且顯示捕獲的變量必須和隱式捕獲使用不同的傳遞方式
pameter list
參數列表和普通函數類似,但是 lambda 不能有 默認參數【lambda 實參和形參數目一定相等】
return type
與普通函數不同的是: lambda 必須使用位尾置返回 來指定返回類型。
如果忽略返回類型,lambda 表達式會根據函數體中的代碼推斷出返回類型
若函數體只有一個 return 語句, 則返回類型從返回表達式的類型推斷而來,否則,若未指定返回類型,返回類型為 void
Note: 如果 lambda 的函數體包含任意單一 return 之外的內容, 且未指定返回類型,則返回 void
當需要為 lambda 定義返回類型時,必須使用尾置返回類型
function body
與常規函數類似
注意:由於lambda實質上是一個匿名類,捕獲列表捕獲的元素在匿名類創建時會拷貝進匿名類的private中,所以建議使用值捕獲,如果使用引用捕獲,容易外部被銷毀。
參考書籍:力扣C++面試