淺談C++11新引入的lambda表達(dá)式
ISO C++ 11 標(biāo)準(zhǔn)的一大亮點(diǎn)是引入Lambda表達(dá)式?;菊Z(yǔ)法如下:
[capture list] (parameter list) ->return type { function body }
簡(jiǎn)單的講一下各個(gè)部分的作用
1.[capture list]捕獲列表,捕獲到函數(shù)體中,使得函數(shù)體可以訪(fǎng)問(wèn)
2.(parameter list)參數(shù)列表,用來(lái)表示lambda表達(dá)式的參數(shù)列表
3.->return type函數(shù)返回值 {function body}就是函數(shù)體
lambda表達(dá)式可以理解為一個(gè)匿名函數(shù)(但本質(zhì)并不是),如果要使用lambda表達(dá)式聲明的函數(shù),需要給他“命名”
lambda表達(dá)式可以表示閉包,因?yàn)楸旧砭褪沁@個(gè)類(lèi)
閉包是指可以包含自由變量的代碼塊 (未綁定到特定的對(duì)象:舉個(gè)栗子std::function就可以產(chǎn)生一個(gè)對(duì)象,或者一個(gè)未指向任何函數(shù)的函數(shù)指針)
閉包講的通俗一些有以下幾點(diǎn)
1.自帶上下文的函數(shù),閉包可以?xún)?chǔ)存運(yùn)行時(shí)需要的上下文,這樣就可以在上下文不存在的時(shí)候還可以使用閉包(變量a生命周期到了被銷(xiāo)毀,但是在閉包中還可以拿來(lái)用)
2.可以把閉包看成一個(gè)重載了operator()的類(lèi),帶有狀態(tài)的意思就可以解釋成通過(guò)this指針使用成員變量
3.capture list就是lambda表達(dá)式實(shí)現(xiàn)閉包的方式
簡(jiǎn)單使用的例子
--------------------------------------------------------------------------------
C++11為auto提供了新的功能,如他的名字一般,現(xiàn)在可以看成自動(dòng)適應(yīng)類(lèi)型,可以適應(yīng)多數(shù)類(lèi)型
使用auto來(lái)代替變量的類(lèi)型,前提是被明確類(lèi)型的初始化變量初始化的,可以使用auto關(guān)鍵字
auto f = [](){};
auto f = [](int a, int b)->int {return a + b; };
f(1, 2);//需要這么使用
只要是函數(shù)類(lèi)型就都可以使用這個(gè)lambda表達(dá)式
typedef int(*FUNC)(int a, int b);
int main()
{
FUNC a= [](int a, int b) {return a + b; };
printf("%d\n", a(1, 2));
}
聲明函數(shù)的方法都可以接收不帶捕獲列表的lambda表達(dá)式
typedef std::function<int(int a, int b)> FUNC;
int main()
{
FUNC a= [](int a, int b) {return a + b; };
printf("%d\n", a(1, 2));
}
--------------------------------------------------------------------------------
lambda表達(dá)式中capture list的用法
int func(int a, int b, std::function<int(int, int)> f)
{
return f(a, b);
}
int a=1;
int b=2;
int c=3;
int d = func(a, b, [a, &b](int m, int n) {
printf("a = %d\n", a); // a是通過(guò)值傳遞捕獲,mutable只在函數(shù)體內(nèi)修改有效
printf("b = %d\n", b); // b是引用傳遞捕獲,mutable可以對(duì)外部b造成影響
//printf("c = %d\n", c); // c不可訪(fǎng)問(wèn)
return m + n;
});
typedef int(*FUNC)(int m, int n,std::function<int(int ,int )> f);
void test()
{
FUNC oho;
int a = 10;
int b = 20;
auto func = [&a, &b](int m, int n) {printf("a:%d b:%d\n", a, b); return m + n; };
}
1.[]空。沒(méi)有使用任何函數(shù)對(duì)象參數(shù)。
2.[=]。函數(shù)體內(nèi)可以使用Lambda所在作用范圍內(nèi)所有可見(jiàn)的局部變量(包括Lambda所在類(lèi)的this),并且是值傳遞方式(相當(dāng)于編譯器自動(dòng)為我們按值傳遞了所有局部變量)。
3.[&]。函數(shù)體內(nèi)可以使用Lambda所在作用范圍內(nèi)所有可見(jiàn)的局部變量(包括Lambda所在類(lèi)的this),并且是引用傳遞方式(相當(dāng)于編譯器自動(dòng)為我們按引用傳遞了所有局部變量)。
4.[this]。函數(shù)體內(nèi)可以使用Lambda所在類(lèi)中的成員變量。
5.[a]。將a按值進(jìn)行傳遞。按值進(jìn)行傳遞時(shí),函數(shù)體內(nèi)不能修改傳遞進(jìn)來(lái)的a的拷貝,因?yàn)槟J(rèn)情況下函數(shù)是const的。要修改傳遞進(jìn)來(lái)的a的拷貝,可以添加mutable修飾符。
6.[&a]。將a按引用進(jìn)行傳遞。
7.[a, &b]。將a按值進(jìn)行傳遞,b按引用進(jìn)行傳遞。
8.[=,&a, &b]。除a和b按引用進(jìn)行傳遞外,其他參數(shù)都按值進(jìn)行傳遞。注意=符號(hào)的位置必須在頭一個(gè)
9.[&, a, b]。除a和b按值進(jìn)行傳遞外,其他參數(shù)都按引用進(jìn)行傳遞。&符號(hào)的位置必須在頭一個(gè)
當(dāng)你想改變通過(guò)傳值方式捕捉的變量的時(shí)候就要添加mutable
[a, &b, &b2](int m, int n)mutable {a *= 2; return m*n; }:
--------------------------------------------------------------------------------
lambda表達(dá)式的其他用法
class A
{
public:
A();
~A();
void test()
{
auto f = [this](int m, int n) {printf("%d\n", a); };
}
private:
int a;
};
lambda表達(dá)式本質(zhì)是一種閉包類(lèi)型,雖然他可以賦值給函數(shù)指針,但是只限于在捕獲列表為空的時(shí)候,當(dāng)捕獲列表有值的時(shí)候,應(yīng)該使用auto來(lái)接收l(shuí)ambda表達(dá)式,或者用std::function也是可以的
main::__l2::<lambda_eb7b0a89c14bee3d2620c108ffb635c6>
//這是一個(gè)lambda表達(dá)式在VS2015環(huán)境下顯示的類(lèi)型,不用auto用什么來(lái)接收調(diào)用他呢?
本質(zhì)來(lái)說(shuō)lambda表達(dá)式之間是不允許賦值的
auto a = [](int m, int n) {return m + n; };
auto b = [](int m, int n) {return m - n; };
a = b;
操作非法,因?yàn)殚]包類(lèi)型不允許使用賦值操作符,但是函數(shù)指針可以,也就是可以有下面的操作
typedef int(*FUNC)(int a, int b);
int main()
{
FUNC a = [](int a, int b) {return a + b; };
FUNC b = [](int a, int b) {return a + b; };
a = b;
return 0;
}
std::function之間也是可以賦值的,他就可以辦到有capture list的lambda表達(dá)式進(jìn)行賦值
typedef std::function<int(int,int)> FUNC;
int m = 10;
int n = 20;
FUNC a = [m, n](int a, int b){printf("%d\n", m); return a + b; };
FUNC b = [m, n](int a, int b){return a + b; };
b = a;
b(1, 2);
//執(zhí)行結(jié)果是可以把m打印出來(lái)的
以上就是本文給大家介紹的c++11的新特性lambda表達(dá)式的全部?jī)?nèi)容了,希望大家能夠喜歡
- C++11中l(wèi)ambda、std::function和std:bind詳解
- C++11/14 線(xiàn)程中使用Lambda函數(shù)的方法
- 結(jié)合C++11新特性來(lái)學(xué)習(xí)C++中l(wèi)ambda表達(dá)式的用法
- 淺析C++11新特性的Lambda表達(dá)式
- 一文讀懂c++11 Lambda表達(dá)式
- C++11 lambda表達(dá)式在回調(diào)函數(shù)中的使用方式
- C++11?lambda(匿名函數(shù))表達(dá)式詳細(xì)介紹
- C++11中的可變參數(shù)模板/lambda表達(dá)式
- 深入解析C++11?lambda表達(dá)式/包裝器/線(xiàn)程庫(kù)
- 深入理解C++11:探索lambda函數(shù)的奧秘
相關(guān)文章
詳解C++編程中的主表達(dá)式與后綴表達(dá)式編寫(xiě)基礎(chǔ)
這篇文章主要介紹了C++編程中的主表達(dá)式與后綴表達(dá)式編寫(xiě)基礎(chǔ),是C++入門(mén)學(xué)習(xí)中的基礎(chǔ)知識(shí),需要的朋友可以參考下2016-01-01
C語(yǔ)言中strspn()函數(shù)和strcspn()函數(shù)的對(duì)比使用
這篇文章主要介紹了C語(yǔ)言中strspn()函數(shù)和strcspn()函數(shù)的對(duì)比使用,strspn是計(jì)算屬于字符串的字符數(shù)而strcspn則是判斷不屬于,需要的朋友可以參考下2015-08-08
Qt實(shí)現(xiàn)TCP客戶(hù)端和服務(wù)器通訊程序
這篇文章主要為大家詳細(xì)介紹了Qt實(shí)現(xiàn)TCP客戶(hù)端和服務(wù)器通訊程序,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-08-08
C++控制臺(tái)強(qiáng)化如何實(shí)現(xiàn)一定界面效果(簡(jiǎn)潔版)
這篇文章主要介紹了C++控制臺(tái)強(qiáng)化如何實(shí)現(xiàn)一定界面效果(簡(jiǎn)潔版),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-07-07
詳解如何在C/C++中測(cè)量一個(gè)函數(shù)或功能的運(yùn)行時(shí)間
本文算是一個(gè)比較完整的關(guān)于在 C/C++ 中測(cè)量一個(gè)函數(shù)或者功能的總結(jié),最后會(huì)演示三種方法的對(duì)比,文章通過(guò)代碼示例給大家介紹的非常詳細(xì),需要的朋友可以參考下2023-12-12
C++實(shí)現(xiàn)評(píng)教管理系統(tǒng)
這篇文章主要為大家詳細(xì)介紹了C++實(shí)現(xiàn)評(píng)教管理系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-03-03

