C++ Lambda表達(dá)式詳解

一、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)方式。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末芍躏,一起剝皮案震驚了整個(gè)濱河市邪乍,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌对竣,老刑警劉巖庇楞,帶你破解...
    沈念sama閱讀 217,084評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異否纬,居然都是意外死亡吕晌,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,623評論 3 392
  • 文/潘曉璐 我一進(jìn)店門临燃,熙熙樓的掌柜王于貴愁眉苦臉地迎上來睛驳,“玉大人烙心,你說我怎么就攤上這事》Ψ校” “怎么了淫茵?”我有些...
    開封第一講書人閱讀 163,450評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長屎蜓。 經(jīng)常有香客問我痘昌,道長,這世上最難降的妖魔是什么炬转? 我笑而不...
    開封第一講書人閱讀 58,322評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮算灸,結(jié)果婚禮上扼劈,老公的妹妹穿的比我還像新娘。我一直安慰自己菲驴,他們只是感情好荐吵,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,370評論 6 390
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著赊瞬,像睡著了一般先煎。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上巧涧,一...
    開封第一講書人閱讀 51,274評論 1 300
  • 那天薯蝎,我揣著相機(jī)與錄音,去河邊找鬼谤绳。 笑死占锯,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的缩筛。 我是一名探鬼主播消略,決...
    沈念sama閱讀 40,126評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼瞎抛!你這毒婦竟也來了艺演?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,980評論 0 275
  • 序言:老撾萬榮一對情侶失蹤桐臊,失蹤者是張志新(化名)和其女友劉穎胎撤,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體豪硅,經(jīng)...
    沈念sama閱讀 45,414評論 1 313
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡哩照,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,599評論 3 334
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了懒浮。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片飘弧。...
    茶點(diǎn)故事閱讀 39,773評論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡识藤,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出次伶,到底是詐尸還是另有隱情痴昧,我是刑警寧澤,帶...
    沈念sama閱讀 35,470評論 5 344
  • 正文 年R本政府宣布冠王,位于F島的核電站赶撰,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏柱彻。R本人自食惡果不足惜豪娜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,080評論 3 327
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望哟楷。 院中可真熱鬧瘤载,春花似錦、人聲如沸卖擅。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,713評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽惩阶。三九已至挎狸,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間断楷,已是汗流浹背锨匆。 一陣腳步聲響...
    開封第一講書人閱讀 32,852評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留脐嫂,地道東北人统刮。 一個(gè)月前我還...
    沈念sama閱讀 47,865評論 2 370
  • 正文 我出身青樓,卻偏偏與公主長得像账千,于是被迫代替她去往敵國和親侥蒙。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,689評論 2 354

推薦閱讀更多精彩內(nèi)容

  • 1. 概述 C++ 11 中的 Lambda 表達(dá)式用于定義并創(chuàng)建匿名的函數(shù)對象匀奏,以簡化編程工作鞭衩。Lambda 的...
    googoler閱讀 3,722評論 0 1
  • lambda表達(dá)式 目錄 一、開篇 二娃善、lambda初識(shí) 三论衍、lambda基本用法 四、lambda表達(dá)式捕獲列表...
    開源519閱讀 207評論 0 0
  • Lambda表達(dá)式聚磺,也稱為匿名函數(shù)坯台、閉包函數(shù),在別的編程語言很早就有了瘫寝。 C++ 11開始蜒蕾,也支持了這個(gè)功能稠炬。而后...
    王玉川閱讀 270評論 0 0
  • 技術(shù)交流QQ群:1027579432,歡迎你的加入咪啡! 1.Lambda函數(shù)與表達(dá)式 C++11提供了對匿名函數(shù)的支...
    CurryCoder閱讀 5,624評論 1 3
  • C++中一共有5種調(diào)用對象:函數(shù)首启,函數(shù)指針,重載了函數(shù)調(diào)用運(yùn)算符的類(仿函數(shù))撤摸,bind創(chuàng)建的對象 和 lambd...
    wayyyy閱讀 530評論 0 0