C++lambda表達式


摘錄一段簡單的Code

我也不是文藝的人,對於Lambda的歷史,以及Lambda與C++的那段淵源,我也不是很熟悉,技術人,講究拿代碼說事。


一,lambda的基本語法

當我第一次看到這段代碼時,我直接凌亂了,直接看不懂啊。初識lambda,寫了點對lambda表達式的一些總結。

#include<iostream>
using namespace std;

int main()
{
int a = 1;
int b = 2;
auto func = [=, &b](int c)->int {return b += a + c; };
cout << func(3) << endl;
return 0;
}
    

🧡🧡先來看看lambda的基本語法:

[capture](parameters) mutable ->return-type{statement}
  • [capture]:捕捉列表。捕捉列表總是出現在Lambda函數的開始處。實際上,[]是Lambda引出符。編譯器根據該引出符判斷接下來的代碼是否是Lambda函數。捕捉列表能夠捕捉上下文中的變量以供Lambda函數使用
  • (parameters):參數列表。與普通函數的參數列表一致。如果不需要參數傳遞,則可以連同括號“()”一起省略
  • mutable:mutable修飾符。默認情況下,Lambda函數總是一個const函數,mutable可以取消其常量性。在使用該修飾符時,參數列表不可省略(即使參數為空)
  • ->return-type:這是lambda函數的返回類型。注意這個是一體的,如果需要省略這塊代碼全部省略。省略后,c++會自動推導返回類型,默認是int
  • {statement}:函數體。內容與普通函數一樣,不過除了可以使用參數之外,還可以使用所有捕獲的變量。

與普通函數最大的區別是,除了可以使用參數以外,Lambda函數還可以通過捕獲列表[ ]訪問一些上下文中的數據。具體地,捕捉列表描述了上下文中哪些數據可以被Lambda使用,以及使用方式(以值傳遞的方式或引用傳遞的方式)。語法上,在“[]”包括起來的是捕捉列表,捕捉列表由多個捕捉項組成,並以逗號分隔。捕捉列表有以下幾種形式:

  1. [var]表示值傳遞方式捕捉變量var;
  2. [=]表示值傳遞方式捕捉所有父作用域的變量(包括this);
  3. [&var]表示引用傳遞捕捉變量var;
  4. [&]表示引用傳遞方式捕捉所有父作用域的變量(包括this);
  5. [this]表示值傳遞方式捕捉當前的this指針。

上面提到了一個父作用域,也就是包含Lambda函數的語句塊,說通俗點就是包含Lambda的“{}”代碼塊。上面的捕捉列表還可以進行組合,例如:

  1. [=,&a,&b]表示以引用傳遞的方式捕捉變量a和b,以值傳遞方式捕捉其它所有變量;
  2. [&,a,this]表示以值傳遞的方式捕捉變量a和this,引用傳遞方式捕捉其它所有變量。

不過值得注意的是,捕捉列表不允許變量重復傳遞。下面一些例子就是典型的重復,會導致編譯時期的錯誤。例如:

  • [=,a]這里已經以值傳遞方式捕捉了所有變量,但是重復捕捉a了,會報錯的;
  • [&,&this]這里&已經以引用傳遞方式捕捉了所有變量,再捕捉this也是一種重復。

二,Lambda的使用

個人理解,lambda在c++作用主要是作為內嵌函數,邏輯更加清楚,代碼可讀性更好。即不用先定義函數,再去使用。可以直接使用(類似匿名函數)。

#include <iostream> 
using namespace std;

void main()
{
    int a = 3;
    int b = 4;
    //值傳遞
    auto f1 = [=]()mutable //取消常量屬性(因為要修改a的值)
    {
        a = 3;
        return a + 2;
    };
    //引用傳遞
    auto f2 = [&]
    {
        b = 1;
        return b + 4;
    };
    cout<<"函數f1輸出結果:" << f1() << endl;
    cout <<"a的值:" << a << endl;
    cout <<"函數f2輸出結果:" << f2() << endl;
    cout <<"b的值:" << b << endl;
}
    

 運行結果:

 從結果中還可以看到,值傳遞沒有改變a初始化的值,而引用傳遞改變了b初始化的值。

 再來回顧開頭的那段代碼:

#include<iostream>
using namespace std;

int main()
{
int a = 1;
int b = 2;
auto func = [=, &b](int c)->int {return b += a + c; };
cout << func(3) << endl;
return 0;
}
    

  可以看到,func的參數列表是(int c)。將c=3帶入函數體中:2+=1+3 即輸出結果為6。(由於返回的是b的值,即需要改變b 的值。因此對b用了引用傳值)

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM