1. 程式人生 > 其它 >lambda 表示式(匿名函式)的具體應用和使用場景

lambda 表示式(匿名函式)的具體應用和使用場景

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++面試