c 中lambda表示式的用法

2021-08-10 19:04:28 字數 2626 閱讀 5008

c++11提供了對匿名函式的支援,稱為lambda函式(也叫lambda表示式)。lambda表示式把函式看作物件。lambda表示式可以像物件一樣使用,比如將它們賦給變數和作為引數傳遞,還可以像函式一樣對其求值。lambda表示式本質上與函式宣告非常類似。lambda表示式具體形式如下:

[capture](parameters)mutable->return-type{}

1.[capture]:捕捉列表,總是出現在lambda函式的開始出,實際上,是lambda引出符。編譯器根據該引出符判斷接下來的**是否是lambda函式。捕捉列表能夠捕捉上下文中的變數以供lambda函式使用;

2.(parameters):引數列表。與普通函式的引數列表一致。如果不需要引數傳遞,則可以連同括號「()」一起省略;

3.mutable:mutable修飾符。預設情況下,lambda函式總是乙個const函式,mutable可以取消其常量性。在使用該修飾符時,引數列表不可省略(即使引數為空);

4.->return-type:返回型別。用追蹤返回型別形式宣告函式的返回型別。我們可以在不需要返回值的時候也可以連同符號」->」一起省略。此外,在返回型別明確的情況下,也可以省略該部分,讓編譯器對返回型別進行推導;

5.:函式體。內容與普通函式一樣,不過除了可以使用引數之外,還可以使用所有捕獲的變數。

與普通函式最大的區別是,除了可以使用引數以外,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,引用傳遞方式捕捉其它所有變數。

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

3.[=,a]這裡已經以值傳遞方式捕捉了所有變數,但是重複捕捉a了,會報錯的;

4.[&,&this]這裡&已經以引用傳遞方式捕捉了所有變數,再捕捉this也是一種重複。

例項一:

#include 

using

namespace

std;

int main();

auto func2 = [&];

cout

<< func1() << endl;

cout

<< func2() << endl;

a++;

cout

<< func1() << endl;

cout

<< func2() << endl;

return

0;}

輸出結果為:

11

1111

12

為什麼第三個結果是11,而第四個結果是12呢?這是因為在func1表示式中,a被視為乙個常量,一旦初始化後不會再改變,可以認為是在表示式中copy了乙個跟a同名的const變數,而在func2表示式中,a仍然在使用父作用域中的值,所以使用lambda函式的時候,如果需要捕捉的值成為lambda函式的常量,我們通常會使用按值傳遞的方式捕捉;相反的,如果需要捕捉的值成為lambda函式執行時的變數,則應該採用按引用方式進行捕捉。

例項二:

#include 

using

namespace

std;

int main()() << endl;

cout

<< [&]() << endl;

return

0;}

編譯會報錯,說a是唯讀的,換成下面的**就可以了。

#include 

using

namespace

std;

int main()() << endl;

cout

<< [&]() << endl;

return

0;}

這是因為預設情況下,lambda函式總是乙個const函式,mutable可以取消其常量性。按照規定,乙個const的成員函式是不能在函式體內修改非靜態成員變數的值。

總結:捕捉器這一塊,如果使用按值傳遞,就相當於在表示式定義那一刻,表示式內部就copy了乙份變數,而且值永遠不變,即使表示式被多個地方呼叫,外部變數的變化不影響內部,如果想在表示式內部改變變數的值,需要加mutable關鍵字;如果是按引用傳遞,那麼表示式使用的值就是外部的變數的值,外部的變數值改變,那麼表示式內部得到的值也會改變,表示式內部也可以改變該變數,而且不需要加mutable關鍵字。

lambda表示式用法

lambda 表示式實際上是乙個函式,只是它沒有名字,叫匿名函式。c 11新增了lambda函式,其基本格式如下 捕捉列表 引數 mutable 返回值型別一 c 中使用lambda 捕捉列表 也叫 外部變數訪問方式說明符 可以是 或 表示 中用到的 定義在 外面的變數在 中是否允許被改變。表示不允...

Lambda表示式用法

c 2.0的匿名方法允許我們以內聯的方式來實現委 託例項,而c 3.0的lambda表示式允許我們使用一 種更接近人的思維 更自然的方式來實現類似於匿 名方法同樣的效果。lambda表示式格式為 引數列表 表示式或者語句塊 可以有多個引數,乙個引數,或者無引數。引數型別 可以隱式或者顯式。例如 x,...

Lambda表示式的用法

1 函式式程式設計思想概述 在數學中,函式就是有輸入量 輸出量的一套計算方案,也就是 拿什麼東西做什麼事情 相對而言,物件導向過分強調 必須通過物件的形式來做事情 而函式式思想則盡量忽略物件導向的複雜語法 強調做什麼,而不是以什麼形式做。2 lambda標準格式 lambda省去物件導向的條條框框,...