C 11中的匿名函式(lambda)

2021-10-23 19:36:18 字數 2746 閱讀 4294

c++11提供了對匿名函式的支援,稱為lambda函式(也叫lambda表示式)。

下面舉了幾個lambda函式的例子:

(int x, int y)  // 隱式返回型別

(int& x) // 沒有return語句 -> lambda 函式的返回型別是'void'

() // 沒有引數,僅訪問某個全域性變數

// 與上乙個相同,省略了()

指定返回型別:

(int x, int y) -> int
在這個例子中建立了乙個臨時變數z來儲存中間值。和普通函式一樣,這個中間值不會儲存到下次呼叫。什麼也不返回的lambda函式可以省略返回型別,而不需要使用 -> void 形式。

lambda表示式的語法定義如下:

[capture] (parameters) mutable ->return-type ;

(1) [capture]: 捕捉列表。捕捉列表總是出現在lambda函式的開始處。實質上,是lambda引出符(即獨特的標誌符)

編譯器根據該引出符判斷接下來的**是否是lambda函式

捕捉列表能夠捕捉上下文中的變數以供lambda函式使用

捕捉列表由乙個或多個捕捉項組成,並以逗號分隔,捕捉列表一般有以下幾種形式:

<1> [var] 表示值傳遞方式捕捉變數var

<2> [=] 表示值傳遞方式捕捉所有父作用域的變數(包括this指標)

<3> [&var] 表示引用傳遞捕捉變數var

<4> [&] 表示引用傳遞捕捉所有父作用域的變數(包括this指標)

<5> [this] 表示值傳遞方式捕捉當前的this指標

<6> [=,&a,&b] 表示以引用傳遞的方式捕捉變數 a 和 b,而以值傳遞方式捕捉其他所有的變數

<7> [&,a,this] 表示以值傳遞的方式捕捉 a 和 this,而以引用傳遞方式捕捉其他所有變數

備註:父作用域是指包含lambda函式的語句塊

另外,需要注意的是,捕捉列表不允許變數重複傳遞。下面的例子就是典型的重複,會導致編譯錯誤:

[=, a] 這裡 = 已經以值傳遞方式捕捉了所有的變數,那麼再捕捉 a 屬於重複

[&,&this] 這裡 & 已經以引用傳遞方式捕捉了所有變數,那麼再捕捉 this 屬於重複

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

(3)mutable : mutable修飾符。預設情況下,lambda函式總是乙個const函式,mutable可以取消其常量性(後面有詳解)

在使用該修飾符時,引數列表不可省略(即使引數為空)

(4)->return-type : 返回型別。用追蹤返回型別形式宣告函式的返回型別。

出於方便,不需要返回值的時候也可以連同符號->一起省略

此外,在返回型別明確的情況下,也可以省略該部分,讓編譯器對返回型別進行推導

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

在lambda函式的定義中,引數列表和返回型別都是可選的部分,而捕捉列表和函式體都可能為空

那麼,在極端情況下,c++11中最為簡單的lambda函式只需要宣告為:

{};就可以了.

lambda函式可以引用在它之外宣告的變數。這些變數的集合叫做乙個閉包,閉包被定義在lambda表示式宣告中的方括號內。這個機制允許這些變數被按值或按引用捕獲。

引用示例:

float f0 = 1.0f;

float f1 = 10.0f;

std::cout << [=, &f0](float a) (-3.5); // 輸出結果: 14.5

std::cout << '\n' << f0 << '\n'; // 輸出結果: 14.5

lambda函式是乙個依賴於實現的函式物件型別,這個型別的名字只有編譯器知道。如果使用者想把lambda函式做為乙個引數來傳遞嗎,那麼形參的型別必須是模板型別或者必須能建立乙個std::function類似的物件去捕獲lambda函式。使用 auto關鍵字可以幫助儲存lambda函式,

auto my_lambda_func = [&](int x) ;

auto my_onheap_lambda_func = new auto([=](int x) );

匿名函式儲存在變數,陣列或vector中,並把它們當做命名引數來傳遞:

#include#include#includedouble eval(std::functionf, double x = 2.0)

int main()

; auto f1 = (double x);

decltype(f0) fa[3] = };

std::vectorfv = ;

fv.push_back ((double x));

for(int i=0;i乙個沒有指定任何捕獲的lambda函式,可以顯式轉換成乙個具有相同宣告形式函式指標。所以,像下面這樣做是合法的:

auto a_lambda_func = (int x) ;

void(*func_ptr)(int) = a_lambda_func;

func_ptr(4); //calls the lambda.

c 11匿名函式Lambda

定義乙個lambda函式 auto f capture params opt ret f 呼叫函式其中 capture表示捕獲函式作用域外的外部變數 params是引數 非必須 opt是函式選項,例如可選擇是否允許更改capture到的外部變數 ret表示函式返回型別,一般可以免了,因為我們在f前面...

lambda 函式或者匿名函式(C 11)

lambda 函式也就是沒有名字的函式,一般情況下,在任何地方,如果需要把乙個函式作為引數給出,但你寧願給出乙個簡短即時函式定義,而不是乙個指向原始檔其他地方或者另乙個模組中提供的定義的指標時,lambda 函式可能是有用的,lambda 函式可以作為 動態 給出的乙個快捷方便的函式,而不是正式定義...

C 11新特性 Lambda函式(匿名函式)

c 11終於知道要在語言中加入匿名函式了。匿名函式在很多時候可以為編碼提供便利,這在下文會提到。很多語言中的匿名函式,如c 都是用lambda表示式實現的。lambda表示式又稱為lambda函式。我在下文中稱之為lambda函式。為了明白lambda函式的用處,請務必先搞明白c 中的自動型別推斷 ...