C 11 之 lambda函式的詳細使用

2021-10-04 12:54:14 字數 3541 閱讀 1379

lambda 表示式是一種匿名函式,即沒有函式名的函式;該匿名函式是由數學中的λ演算而來的。通常情況下,lambda函式的語法定義為:

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

其中:[capture] :捕捉列表。捕捉列表總是作為lambda的開始,即出現於lambda的開始處。它是lambda的引出符(即開始標誌)。編譯器可以根據該「標誌」來作出判斷出該函式是否為lambda函式。同時「捕捉列表」能夠捕捉上下文中的變數以作為lambda函式使用。

(parameters):引數列表。和c/c++中的普通函式引數意義一樣。該部分是可選的,意味著如果我們不需要進行引數傳遞時,可以連同括號「()」一起省略掉。

mutable:該關鍵字為乙個修飾符。在預設的情況下,lambda函式總是返回乙個const,而當我們在引數列表後面註明了「mutable」關鍵字之後,則可以取消其常量性質。若在lambda中使用了mutable修飾符,則「引數列表」是不可省略掉的(即使是引數為空)。

->return-type:函式的返回值型別。和c/c++中的普通函式返回值型別的性質一樣。主要目的是用來追蹤lambda函式(有返回值情況下)的返回型別。若lambda函式不需要返回值,則可以直接將這部分省略掉。

函式體。在該函式體中,除了可以使用引數列表中的變數外,還可以使用所有捕獲到的變數(即[capture] 中的變數)。

見下圖:

c++11中的lambda函式,其中的「捕捉列表」是由0個或多個「捕捉項」組成,並以逗號「,」分隔。捕捉列表有如下幾種形式:

(1)[var] 表示值傳遞方式捕捉變數var。

#include #include #include using namespace std;

int main()

;   printf("sum[%d]\n",retval());

printf("a[%d] b[%d] c[%d]\n",a,b,c);

return 0;

}

列印結果:

inner c[3]

sum[30]

a[10] b[20] c[3]

上面的**中,「捕捉列表」由3項組成。以引用傳遞的方式捕捉變數a、b,以值傳遞的方式捕捉變數c。因此在lambda表示式的函式體中修改了變數a和b之後,父作用域中的a、b值也改變。而即使是在lambda函式內部修改了變數c的值,父作用域中的c仍然不會受到影響,因為是值傳遞的方式。(需在引數列表後面加上 mutable 關鍵字(修飾符))。同時

#include #include #include using namespace std;

int main()

;   printf("sum[%d]\n",retval());

printf("a[%d] b[%d] c[%d]\n",a,b,c);

return 0;

}

列印結果:

inner c[3]

inner c2[30]

sum[30]

a[10] b[20] c[3]

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

(3)[&var] 表示引用傳遞捕捉變數var。

(4)[&] 表示引用傳遞捕捉所有父作用域的比**(2020-02-18 09:36:12 修改) 的變數(包括this)。

#include #include #include using namespace std;

int main()

;   printf("sum[%d]\n",retval());

printf("a[%d] b[%d] c[%d]\n",a,b,c);

return 0;

}

列印結果:

inner a[1] b[2] c[3]

sum[30]

a[10] b[20] c[30]

(5)[this] 表示值傳遞方式捕捉當前的this指標。

同理(2),(3),(5)可以參考上面的兩個例子。

(1)在c++11中,lambda函式是inline(內聯函式)。

**一

#include #include #include using namespace std;

int main()

;   printf("sum[%d]\n",sum(a,b));

return 0;

}

//列印結果:sum[14]

在**一中,定義了乙個簡單的lambda函式,該函式的函式列表能夠接收兩個int型別的資料,而且返回值為int型別。

注意:lambda函式中,引數列表和返回型別都是可選的部分,而且捕捉列表和函式也可以為空。因此,在某種情況下,c++11中的簡略版本的lambda函式可以是這樣的:

// 完整語法

[ capture-list ] ( params ) mutable(optional) constexpr(optional)(c++17) exception attribute -> ret

// 可選的簡化語法

[ capture-list ] ( params ) -> ret     

[ capture-list ] ( params )

最為簡潔的版本如下

[ capture-list ]

測試**二

#include #include #include #include using namespace std;

//lambda 表示式的第一種用法

void lambdauseone()

; printf("sum[%d]\n", retval()); //類似於函式物件的呼叫

printf("a[%d] b[%d] c[%d]\n", a, b, c);

}//lambda 表示式的第二種用法

void lambadausetwo(int a,std::functionone)

//lambda 表示式的第三種用法

void lambdausethree()

(); //直接在函式題後新增括號() 表示直接呼叫

}int main()

); //lambda 表示式的第三種用法

lambdausethree();

system("pause");

return 0;

}

c 11匿名函式Lambda

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

C 11 中的 lambda 函式

lambda 演算是個非常古老的計算機語言領域的技術,這段歷史一直可以追溯到20世紀30年代。程式語言最先引入 lambda 函式的是 lisp 語言。之後 lisp 的各種變種中都保留了 lambda 函式的概念。這裡不準備就 lambda 函式的歷史展開介紹。主要是說說 c 11 標準中的 la...

c 11新特性 lambda函式

lambda歷史悠久,在數理邏輯和電腦科學領域,lambda被用來表示一種匿名函式這種匿名函式代表了一種 演算 lambda calculus 但是在c 領域直到c 11才引入lambda表示式,本文先打算從lambda函式入手 後續會繼續從lambda與仿函式 lambda基礎應用 lambda的...