lambada表达式
lambda表達(dá)式
//C++ 11中的Lambda表達(dá)式用于定義并創(chuàng)建匿名的函數(shù)對象,以簡化編程工作。Lambda的語法形式如下:
//[函數(shù)對象參數(shù)](操作符重載函數(shù)參數(shù))mutable或exception聲明->返回值類型{函數(shù)體 }
?
//可以看到,Lambda主要分為五個(gè)部分:
//[函數(shù)對象參數(shù)]、(操作符重載函數(shù)參數(shù))、mutable或exception聲明、->返回值類型、{函數(shù)體 }。下面分別進(jìn)行介紹。
//一、[函數(shù)對象參數(shù)],標(biāo)識一個(gè)Lambda的開始,這部分必須存在,不能省略。函數(shù)對象參數(shù)是傳遞給編譯器自動(dòng)生成的函數(shù)對象類的構(gòu)造函數(shù)的。
//函數(shù)對象參數(shù)只能使用那些到定義Lambda為止時(shí)Lambda所在作用范圍內(nèi)可見的局部變量(包括Lambda所在類的this)。函數(shù)對象參數(shù)有以下形式:
//1、空。沒有使用任何函數(shù)對象參數(shù)。
//2、 =。函數(shù)體內(nèi)可以使用Lambda所在作用范圍內(nèi)所有可見的局部變量(包括Lambda所在類的this),并且是值傳遞方式(相當(dāng)于編譯器自動(dòng)為我們按值傳遞了所有局部變量)。
//3、&。函數(shù)體內(nèi)可以使用Lambda所在作用范圍內(nèi)所有可見的局部變量(包括Lambda所在類的this),并且是引用傳遞方式(相當(dāng)于編譯器自動(dòng)為我們按引用傳遞了所有局部變量)。
//4、this。函數(shù)體內(nèi)可以使用Lambda所在類中的成員變量。
//5、a。將a按值進(jìn)行傳遞。按值進(jìn)行傳遞時(shí),函數(shù)體內(nèi)不能修改傳遞進(jìn)來的a的拷貝,因?yàn)槟J(rèn)情況下函數(shù)是const的。要修改傳遞進(jìn)來的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)行傳遞。
//9、&, a, b。除a和b按值進(jìn)行傳遞外,其他參數(shù)都按引用進(jìn)行傳遞。
//二、(操作符重載函數(shù)參數(shù)),標(biāo)識重載的()操作符的參數(shù),沒有參數(shù)時(shí),這部分可以省略。參數(shù)可以通過按值(如:(a, b))和按引用(如:(&a, &b))兩種方式進(jìn)行傳遞。
//三、mutable或exception聲明,這部分可以省略。按值傳遞函數(shù)對象參數(shù)時(shí),加上mutable修飾符后,可以修改按值傳遞進(jìn)來的拷貝(注意是能修改拷貝,而不是值本身)。
//exception聲明用于指定函數(shù)拋出的異常,如拋出整數(shù)類型的異常,可以使用throw(int)。
//四、->返回值類型,標(biāo)識函數(shù)返回值的類型,當(dāng)返回值為void,或者函數(shù)體中只有一處return的地方(此時(shí)編譯器可以自動(dòng)推斷出返回值類型)時(shí),這部分可以省略。
//五、{函數(shù)體 },標(biāo)識函數(shù)的實(shí)現(xiàn),這部分不能省略,但函數(shù)體可以為空。
案例1:
#include<functional>
#include<iostream>
#include<vector>
#include<algorithm>
?
usingnamespacestd;
?
//lambda表達(dá)式簡單案例
voidmain()
{
//[函數(shù)對象參數(shù)]、(操作符重載函數(shù)參數(shù))、mutable或exception聲明、->返回值類型、{函數(shù)體 }
??????autofun1 = [](){cout <<"hellochina"<<endl; };
???fun1();
?
???autofun2 = [](inta,intb){returna +b; };
???cout <<fun2(10, 9) <<endl;
?
???std::cin.get();
}
運(yùn)行結(jié)果:
案例2:
#include<functional>
#include<iostream>
#include<vector>
#include<algorithm>
?
usingnamespacestd;
?
voidmain()
{
???vector<int>?myv;
???myv.push_back(1);
???myv.push_back(2);
???myv.push_back(11);
???autofun1 = [](intv){?cout <<v <<endl; };
???//通過這種方式操作myv中的值
???for_each(myv.begin(),myv.end(),fun1);
?
???cout <<"----------------" <<endl;
?
???//直接寫在內(nèi)部,下面的v表示傳遞進(jìn)lambda表達(dá)式的參數(shù)
???for_each(myv.begin(),myv.end(),[](intv)
???{
??????cout <<v <<endl;
???});
?
???std::cin.get();
}
運(yùn)行結(jié)果:
案例3:
#include<functional>
#include<iostream>
#include<vector>
#include<algorithm>
?
usingnamespacestd;
?
voidmain()
{
???vector<int>?myv;
???myv.push_back(1);
???myv.push_back(2);
???myv.push_back(11);
?
???inta = 10;
???// =知道a的存在,可以引用,只能讀,不可以寫,引用當(dāng)前塊語句內(nèi)部的局部變量
???autofun1 = [=](intv){v +=a;?cout <<v <<endl;?};
?
???for_each(myv.begin(),myv.end(),fun1);
???//此時(shí)a沒有被修改
???cout <<a <<endl;
???std::cin.get();
}
運(yùn)行結(jié)果:
案例4:
#include<functional>
#include<iostream>
#include<vector>
#include<algorithm>
?
usingnamespacestd;
?
voidmain()
{
???vector<int>?myv;
???myv.push_back(1);
???myv.push_back(2);
???myv.push_back(11);
?
???inta = 10;
???//引用變量a,相當(dāng)于直接操作a
???autofun1 = [&a](intv){a = 3; v +=a;?cout <<v <<endl;?};
?
???for_each(myv.begin(),myv.end(),fun1);
???//此時(shí)a發(fā)生變化
???cout <<a <<endl;
???std::cin.get();
}
運(yùn)行結(jié)果:
案例5:
#include<functional>
#include<iostream>
#include<vector>
#include<algorithm>
?
usingnamespacestd;
?
voidmain()
{
???[](){cout <<"hellochina"; };//是一個(gè)函數(shù)指針
???[](){cout <<"hellochina";}();//如果沒有定義名稱,如果想調(diào)用lambda表達(dá)式,可以直接在lambda表達(dá)式的最后面加上()
?
???cin.get();
}
運(yùn)行結(jié)果:
案例6:
#include<functional>
#include<iostream>
#include<vector>
#include<algorithm>
?
usingnamespacestd;
?
classtest
{
public:
???vector<int>?myv;
???intnum;
public:
???voidadd()
???{
???????num = 12;
???????myv.push_back(10);
???????myv.push_back(11);
?
???????//[]引用this
???????int?x = 3;
???????autofun1 = [this,x](intv){cout <<v+x+this->num << endl; };
???????//=按照副本引用this,還有當(dāng)前塊語句局部變量,不可以賦值,但是可以讀取
???????//&按照引用的方式操作局部變量,this,可以賦值,可以讀取
???????//副本引用a,[=]??[a]
???????//引用a [&]?[&a]
?
???????autofun2 = [&](intv){cout <<v +x +this->num << endl;x = 3; };
???????for_each(this->myv.begin(),this->myv.end(),fun1);
???????cout <<"-----------------" <<endl;
???????for_each(this->myv.begin(),this->myv.end(),fun2);
???}
};
?
voidmain()
{
???testt;
???t.add();
?
???cin.get();
}
運(yùn)行結(jié)果:
案:7:
#include<functional>
#include<iostream>
#include<vector>
#include<algorithm>
?
usingnamespacestd;
//返回值案例
voidmain()
{
???//double是返回值類型
???autofun1 = []()->double{cout << "hello china" <<endl;return 1; };
???fun1();
?
???//通過decltype(a/b)的方式獲得類型
???autofun2 = [](inta,doubleb)->decltype(a / b){cout << "hello china" <<endl;returna /b; };
???fun2(1, 2.3);
?
???std::cin.get();
}
運(yùn)行結(jié)果:
案例8:
#include<functional>
#include<iostream>
#include<vector>
#include<algorithm>
?
usingnamespacestd;
?
void?main()
{
???inta = 10;
???//mutable使可以改副本了。如果下面的去掉將會(huì)報(bào)錯(cuò)
???autofun1 = [a](intv)mutable->double{v += a;?cout <<v <<endl;a = 3;return 3; };
???cout <<a <<endl;
?
???std::cin.get();
???//運(yùn)行結(jié)果還是10
}
Lambada表達(dá)式補(bǔ)充
| { ??????? auto func = []{return 1; }; ??????? int i = func(); ??????? CCLog("i = %d", i); ??? } ??? //最簡單的lambada表達(dá)式是只要一個(gè)中括號和一個(gè)大括號 ??? //[]捕獲列表 ??? //{}函數(shù)體 ??? //1.捕獲列表,可以放變量名,這里可以用來傳遞函數(shù)體內(nèi)定義的變量 ??? { ??????? int v = 100; ??????? auto func = [v]{return v; }; ??????? int x = func(); ??? } ? ??? //2.捕獲列表,可以捕獲多個(gè)變量 ??? { ??????? int p = 100, q = 200; ??????? auto func = [p, q]{return p + q; }; ??????? int s = func(); ??? } ? ??? // 3.捕獲列表,有引用和傳值兩種方式,傳值不可以改變,引用可以改變,并且改變外部的變量值 ??? { ??????? int p = 100, q = 200; ??????? auto func = [p, &q]{q++;? return p + q; }; ??????? int s = func(); ??? } ? ??? //4.捕獲列表,可以定義mutable類型的lambada,能改變傳值的捕獲參數(shù), ??? //但是不能改變外部的變量值 ??? { ??????? int p = 100, q = 200; ??????? auto func = [p, q]()mutable{p++; q++; return p + q; }; ??????? int s = func(); ??????? CCLog("p = %d,q = %d,s = %d", p, q, s); ??? } ? ??? //5.捕獲列表,可以用=或者&捕獲所有變量,=指傳值,&表示引用 ??? { ??????? int p = 100, q = 200; ??????? //用&的時(shí)候,所有的都可以調(diào)用了,[&,p]:表示除了p不能被使用,其它的都可以被使用 ??????? auto func = [&]{ ??????????? return p + q; ??????? }; ??? } ? ??? //稍微復(fù)雜點(diǎn)的lambda表達(dá)式 ??? { ??????? auto add = [](int v1, int v2){return v1 + v2; }; ??????? auto a = add(1 , 2); ??? } ? ??? //小括號中的是參數(shù)列表,參數(shù)列表和捕獲列表區(qū)別在于,參數(shù)列表的參數(shù)由調(diào)用方?jīng)Q定, ??? //捕獲列表由定義方?jīng)Q定,所以更加靈活 ? ??? //更加復(fù)雜的lambada表達(dá)是,有返回值,返回值一般都省略 ??? { ??????? //->int表示返回值是int類型的 ??????? auto add = [](int v1, int v2)->int{return v1 + v2; }; ??? } ? ??? //總結(jié):auto func = [](){} ??? { ??????? auto func = [](){}; ??? } |
?
?
總結(jié)
以上是生活随笔為你收集整理的lambada表达式的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 征信报告去哪里打
- 下一篇: STL算法find,find_if,fi