一、Lambda表達(dá)式的介紹
c++11引入了Lambda表達(dá)式放坏,使得開發(fā)人員可以更方便的創(chuàng)建匿名函數(shù)溉苛。Lambda表達(dá)式是c++語言的一個(gè)重要特性凤巨,它可以作為函數(shù)對象使用,可以用來替代一些繁瑣的函數(shù)聲明和定義。
二谎砾、Lambda表達(dá)式的語法
Lambda表達(dá)式的基本語法結(jié)構(gòu)如下:
[capture list] (parameter list) specifiers exception -> type { function body }
[capture list]
是捕獲列表较雕,在應(yīng)用中必填扣典。
(parameter list)
是參數(shù)列表痕钢,在應(yīng)用中選填裁着。
specifiers
是限定符棘捣,在應(yīng)用中選填休建。
exception
是異常說明符乍恐,在應(yīng)用中選填。
-> type
是返回值類型测砂,在應(yīng)用中選填茵烈。
{ function body }
是表達(dá)式的函數(shù)體,在應(yīng)用中必填砌些。
下面是一個(gè)簡單的Lambda表達(dá)式:
[](int x, int y){ return x + y; }
這個(gè)Lambda表達(dá)式可以看作是一個(gè)沒有函數(shù)名的函數(shù)瞧毙,接受兩個(gè)整型參數(shù),并返回它們的和寄症。應(yīng)用實(shí)例如下:
auto f = [](int x, int y){ return x + y; };
int result = f(10, 20); //result == 30
三宙彪、Lambda表達(dá)式的捕獲列表
Lambda表達(dá)式的捕獲列表可以捕獲當(dāng)前函數(shù)作用域的零個(gè)或多個(gè)變量,變量之間用逗號(hào)分隔有巧;這些變量可以在Lambda表達(dá)式中被訪問和修改释漆。捕獲方式有三種,分別是值捕獲篮迎、引用捕獲和混合捕獲男图。
值捕獲:將外部變量以const引用的方式傳遞到Lambda表達(dá)式中,在表達(dá)式中可以訪問變量甜橱,但是不能修改變量逊笆;使用=
可以將函數(shù)作用域的所有變量以值捕獲方式傳入到表達(dá)式中。
int a = 10; b = 20, c = 30;
//將變量a和b以值捕獲方式傳入到表達(dá)式中
auto f1 = [a, b]{ return a + b; };
int result1 = f1(); //result1 == 30
//將所有變量以值捕獲方式傳入到表達(dá)式中
auto f2 = [=]{ return a + b + c; };
int result2 = f2(); //result2 == 60
引用捕獲:將外部變量以引用的方式傳遞到Lambda表達(dá)式中岂傲,在表達(dá)式中可以訪問變量和修改變量难裆;使用&可以將函數(shù)作用域的所有變量以引用捕獲方式傳入到表達(dá)式中。
int a = 10; b = 20, c = 30;
//將變量a和b以引用捕獲方式傳入到表達(dá)式中
auto f1 = [&a, &b]{ a++; b++; };
f1();
//a == 11 b == 21
//將所有變量以引用捕獲方式傳入到表達(dá)式中
auto f2 = [&]{ a++; b++; c++; };
f2();
//a == 12 b == 22 c == 31
混合捕獲:捕獲列表捕獲多個(gè)變量镊掖,既有值捕獲的變量也有引用捕獲的變量乃戈。
int a = 10; b = 20, c = 30;
//將變量a和b以值捕獲方式傳入到表達(dá)式中,將變量c以引用捕獲方式傳遞到表達(dá)式中
auto f = [=,&c]{ c++; return a + b; };
int result = f(); //result == 30
//c == 31
四亩进、Lambda表達(dá)式的參數(shù)列表
Lambda表達(dá)式的參數(shù)列表與普通函數(shù)參數(shù)列表一致症虑;如果不需要參數(shù),則可以省略此項(xiàng)归薛。
//沒有參數(shù)
auto f1 = []{ return 1; };
int result1 = f1(); //result1 == 1
//兩個(gè)參數(shù)
auto f2 = [](int x, int y){ return x + y; };
int result2 = f2(10,20); //result2 == 30
五谍憔、Lambda表達(dá)式的限定符
Lambda表達(dá)式的限定符值為mutable,其意義是可以在函數(shù)體內(nèi)修改按值捕獲的變量主籍;如果不需要此操作习贫,則可以省略此項(xiàng)。
int a = 10;
//未用mutable修飾
auto f1 = [a](){
a++; //報(bào)錯(cuò)
}
//使用mutable修飾
auto f2 = [a]() mutable {
a++; //成功
}
六崇猫、Lambda表達(dá)式的異常說明符
Lambda表達(dá)式的異常說明符值為noexcept沈条,其意義是指明表達(dá)式不會(huì)拋出異常;如果不需要此操作诅炉,則可以省略此項(xiàng)蜡歹。
//未用noexcept修飾
auto f1 = [](int x){
if(x == 0)
throw(0); //成功
return x;
}
//使用noexcept修飾
auto f2 = [](int x) noexcept {
if(x == 0)
throw(0); //報(bào)錯(cuò)
return x;
}
七、Lambda表達(dá)式的返回值類型
用-> type
可以指定lambda表達(dá)式返回值類型涕烧;如果不指定返回類型月而,則編譯器會(huì)根據(jù)代碼實(shí)現(xiàn)為函數(shù)推導(dǎo)一個(gè)返回類型;如果沒有返回值议纯,則可忽略此部分父款。
//指定返回值類型
auto f1 = []()->int { return 1; };
int result1 = f1(); //result == 1
//不指定返回值類型
auto f2 = [](){ return 1; };
int result2 = f2(); //result == 1
八、Lambda表達(dá)式的函數(shù)體
Lambda表達(dá)式的函數(shù)體部分與普通函數(shù)體一致。
auto f1 = []{ std::cout << "hello world" << std::endl; };
auto f2 = [](int x, int y){ return x + y; };
九憨攒、Lambda表達(dá)式的優(yōu)缺點(diǎn)
Lambda表達(dá)式有以下優(yōu)點(diǎn):
簡潔:Lambda表達(dá)式可以在一個(gè)表達(dá)式中定義一個(gè)函數(shù)世杀,不需要單獨(dú)聲明和定義。
方便:Lambda表達(dá)式可以捕獲外部變量肝集,使得函數(shù)對象更加靈活和易于使用瞻坝。
通用:Lambda表達(dá)式可以作為任何需要函數(shù)對象的地方使用,例如STL算法杏瞻、線程等所刀。
Lambda表達(dá)式也有一些缺點(diǎn):
可讀性:Lambda表達(dá)式可能過于簡潔,難以閱讀和理解捞挥。
復(fù)雜性:Lambda表達(dá)式可以包含復(fù)雜的邏輯和控制流浮创,使得代碼難以維護(hù)和調(diào)試。
性能:Lambda表達(dá)式可能會(huì)產(chǎn)生額外的開銷砌函,例如變量捕獲和函數(shù)調(diào)用的開銷斩披。
十、結(jié)論
c++Lambda表達(dá)式是一項(xiàng)重要的語言特性胸嘴,它使得開發(fā)人員可以更方便地創(chuàng)建匿名函數(shù)和函數(shù)對象雏掠。Lambda表達(dá)式的語法簡潔、靈活劣像,可以捕獲外部變量乡话,并且可以作為任何需要函數(shù)對象的地方使用。Lambda表達(dá)式也存在一些缺點(diǎn)耳奕,包括可讀性绑青、復(fù)雜性和性能問題。在實(shí)際開發(fā)中屋群,開發(fā)人員應(yīng)該根據(jù)具體情況權(quán)衡利弊闸婴,選擇合適的編程風(fēng)格和實(shí)現(xiàn)方式。