1. lambda表達(dá)式
lambda表達(dá)式 是一個(gè)匿名函數(shù),也就是沒有函數(shù)名的函數(shù)酗电。也叫閉包,閉就是封閉的意思内列,包就是函數(shù)撵术。lambda表達(dá)式 其實(shí)就是一個(gè)函數(shù)對(duì)象,內(nèi)部創(chuàng)建了一個(gè)重載()操作符的類话瞧。
2. lambda的格式
捕獲變量列表-> 返回值類型(函數(shù)主體) 嫩与,lambda可以隱士返回,也就是返回值類型可以不用顯示寫出來交排。
3. 捕獲變量
c++和c#不一樣划滋,想在閉包里面使用外部變量,就必須先在捕獲變量列表里面定義埃篓。有下面幾種定義可供選擇处坪。
[]沒有捕獲任何變量
[=] 按值類型捕獲Lambda 所在范圍內(nèi)所有可見的局部變量
[&] 按引用類型捕獲Lambda 所在范圍內(nèi)所有可見的局部變量
[a] 按值類型捕獲a變量
[&a] 按引用類型捕獲a變量
[&,a] 值類型捕獲a,引用類型捕獲其余變量
[=,&a] 引用類型捕獲a架专,其余按值類型捕獲
[this] 可以使用 Lambda 所在類中的成員變量同窘。
當(dāng)然參數(shù)也可以是多個(gè),比如[a,b,c,&d] [&a,b,&c,d]這樣都是可以的。
注意一點(diǎn)部脚,變量捕獲是在lambda表達(dá)式被創(chuàng)建的時(shí)候想邦。
4. 函數(shù)指針
函數(shù)指針就是即指向函數(shù)的指針。
定義格式一般是 返回值類型(函數(shù)指針名字)(參數(shù))委刘,例如 int (p)(int) double (p)(string) void(*p)(int)都是正確的函數(shù)指針定義丧没。
下面看一個(gè)向函數(shù)指針傳遞lambda的例子:
int main()
{
FunctionTest();
system("pause");
return 0;
}
void FunctionTest()
{
FuncPtrTest([](int b) {cout << b << endl; return b; });
}
void FuncPtrTest(int (*p)(int) )
{
p(1);
}
輸出結(jié)果為 1,在這里我們并沒有用到變量捕獲钱雷,事實(shí)上c++不允許往函數(shù)指針傳遞lambda的時(shí)候進(jìn)行變量捕獲骂铁。下面介紹function。
5. function
類模板std :: function是一個(gè)通用的多態(tài)函數(shù)包裝器罩抗。 std :: function的實(shí)例可以存儲(chǔ)拉庵,復(fù)制和調(diào)用任何可調(diào)用的目標(biāo) :包括函數(shù),lambda表達(dá)式套蒂,綁定表達(dá)式或其他函數(shù)對(duì)象钞支,以及指向成員函數(shù)和指向數(shù)據(jù)成員的指針茫蛹。(這句話是我抄的)
function聲明格式 function<返回值(變量類型)>,例如function<int(int)>烁挟,function<void(int)>都是function的正確聲明婴洼。
void FunctionTest()
{
int a = 0;
function<void(int)> func1 = [a](int b)->void { cout<<"func1\t" << "a=" << a << "\t" << "b=" << b << endl; };
func1(5);
}
上面定義了一個(gè)返回值為void,接受一個(gè)int類型參數(shù)的function函數(shù)模板撼嗓,右邊是一個(gè)lambda表達(dá)式柬采,值類型捕獲a,輸出的結(jié)果是func1 a=0 b=5且警。
再看下面一種情況
void FunctionTest()
{
int a = 0;
function<void(int)> func1 = [a](int b)->void { cout<<"func1\t" << "a=" << a << "\t" << "b=" << b << endl; };
function<int(int)> func2 = [a](int b)->int {cout << "func2\t"; return a + b; };
func1(5);
cout << func2(5) << endl;
}
定義了一個(gè)返回值為void粉捻,接受一個(gè)int類型參數(shù)的function函數(shù)模板,顯式返回a+b的值斑芜,輸出5肩刃;
再看下面的情況
void FunctionTest()
{
int a = 0;
function<void(int)> func1 = [a](int b)->void { cout<<"func1\t" << "a=" << a << "\t" << "b=" << b << endl; };
function<int(int)> func2 = [a](int b)->int {cout << "func2\t"; return a + b; };
function<void(int)> func3 = [&a](int b) {cout << "func3\t" << a + b << endl; a += 5; };
cout << a << endl;
func1(5);
func3(5);
cout << func2(5) << endl;
}
定義了一個(gè)返回值為void,按引用捕獲a變量杏头,接受一個(gè)int類型參數(shù)的function函數(shù)模板盈包,隱式返回void,輸出5醇王,并且在最后改變了a的值a+=5呢燥。
細(xì)心的同學(xué)會(huì)發(fā)現(xiàn),明明先調(diào)用了func3厦画,后調(diào)用func2疮茄,為什么2還是輸出5,那是因?yàn)椴东@變量發(fā)生在lambda被創(chuàng)建的時(shí)候根暑,把func2改成按類型捕獲力试,或者將func3的聲明和調(diào)用放到func2的前面,都會(huì)輸出10排嫌。這一點(diǎn)還是要多多注意