C++中的lambda表達式簡單介紹
一、 什么是lambda表達式
C++中有“可調(diào)用對象”的概念,主要包括函數(shù)指針、仿函數(shù)、lambda表達式。lambda表達式本質(zhì)是一個匿名函數(shù)對象,跟普通函數(shù)不同的是,他可以定義在函數(shù)內(nèi)部。
lambda表達式在語法使用層面上“沒有類型”,簡單來說:lambda表達式的類型是編譯器即時生成的、唯一的、匿名的,程序員無法在代碼中直接寫出它的類型名稱。lambda表達式使用時本質(zhì)是被轉(zhuǎn)換成一個仿函數(shù)再使用的,每個lambda表達式都會被編譯器轉(zhuǎn)換成一個獨一無二的、匿名的類(仿函數(shù))。即使兩個lambda看起來完全一樣,編譯器也會為它們生成兩個不同的類。所以,我們一般都是用auto或者模板參數(shù)定義的對象去接收lambda對象。
二、 表達式語法
lambda表達式的語法格式是:[capture-list](parameters)->return-type {function body}
(parameters):參數(shù)列表。與普通的函數(shù)參數(shù)列表功能類似,如果不需要傳參,則可以連同()一起省略。->return-type:return type是lambda函數(shù)的返回值類型。如果沒有返回值,那么->return type這部分就可以省略,或者返回值類型明確的情況下,能由編譯器自動推導(dǎo)返回類型出來,也能省略這部分。{function body}:函數(shù)體。函數(shù)體的實現(xiàn)與普通函數(shù)完全一樣,函數(shù)體內(nèi)除了能使用參數(shù)列表外,還可以使用捕捉列表內(nèi)的變量。函數(shù)體為空也必須寫{}。[capture-list]:捕捉列表。該列表寫在lambda表達式的開始位置,編譯器根據(jù)[]來判斷接下來的代碼是否為lambda函數(shù)。捕捉列表能夠捕捉上下文的變量,以供lambda函數(shù)內(nèi)部使用,捕捉列表可以傳值或傳引用,捕捉列表就算為空也必須寫[]。
舉幾個栗子:
auto add = [](int x, int y){ return x + y; };
auto func = []
{
cout << "hello world" << endl;
};
auto swap = [](int& a, int& b)
{
int tmp = a;
a = b;
b = tmp;
};

非常好理解吧!
關(guān)于捕捉列表,還有一些使用的細節(jié):
lambda表達式中默認(rèn)只能使用參數(shù)列表中的變量或lambda內(nèi)定義的,如果想使用外層作用域中的變量就需要進行捕捉。
- 第一種方式是顯式捕捉,在捕捉列表中可以顯式傳值捕捉和傳引用捕捉,捕捉的多個變量用逗號分隔,比如
[x, y, &z]表示x和y進行傳值捕捉,lambda內(nèi)部改變x和y不會改變原變量,而z是傳引用捕捉,對z的改變會改變原變量。 - 第二種捕捉方式是隱式捕捉,我們在[ ]中寫一個 = 表示隱式值捕捉,寫一個 & 表示隱式引用捕捉。這樣我們的lambda的表達式中使用了哪些外部變量,編譯器就會自動捕捉那些變量。
- 第三種捕捉列表是混合捕獲,可以組合使用隱式捕獲和顯式捕獲,實現(xiàn)更精細的控制。[=, &x] 表示x進行引用捕捉,其余變量都為值捕捉;[&, x, y] 表示x和y進行值捕捉,其余變量進行引用捕捉。使用混合捕捉時,第一個元素必須是=或&,第一個是=時,后面的捕捉變量必須是引用捕捉;第一個是&時,后面的捕捉變量必須是值捕捉。
lambda表達式中如果在局部域時,可以捕捉到它之前定義的變量,不能捕捉靜態(tài)局部變量和全局變量,因為這兩種變量本來就不需要捕捉也能在內(nèi)部直接使用,lambda表達式內(nèi)部可以直接使用。lambda表達式如果定義在全局位置,捕捉列表必須為空。
默認(rèn)情況下,lambda捕捉列表是const屬性的,也就是說傳值捕捉來的對象不能被修改,在參數(shù)列表后加上修飾符mutable就可以取消其常性,但是修改還是改變的形參對象,不會影響實參。使用該修飾符后參數(shù)列表不能省略。
int x = 0;
// 捕捉列表必須為空,因為全局變量不?捕捉就可以?,沒有可被捕捉的變量
auto func1 = []()
{
x++;
};
int main()
{
// 只能?當(dāng)前l(fā)ambda局部域和捕捉的對象和全局對象
int a = 0, b = 1, c = 2, d = 3;
auto func1 = [a, &b]
{
// 值捕捉的變量不能修改,引?捕捉的變量可以修改
//a++;
b++;
int ret = a + b;
return ret;
};
cout << func1() << endl;
// 隱式值捕捉
// ?了哪些變量就捕捉哪些變量
auto func2 = [=]
{
int ret = a + b + c;
return ret;
};
cout << func2() << endl;
// 隱式引?捕捉
// ?了哪些變量就捕捉哪些變量
auto func3 = [&]
{
a++;
c++;
d++;
};
func3();
cout << a << " " << b << " " << c << " " << d << endl;
// 混合捕捉1
auto func4 = [&, a, b]
{
//a++;
//b++;
c++;
d++;
return a + b + c + d;
};
func4();
cout << a << " " << b << " " << c << " " << d << endl;
// 混合捕捉1
auto func5 = [=, &a, &b]
{
a++;
b++;
/*c++;
d++;*/
return a + b + c + d;
};
func5();
cout << a << " " << b << " " << c << " " << d << endl;
// 局部的靜態(tài)和全局變量不能捕捉,也不需要捕捉
static int m = 0;
auto func6 = []
{
int ret = x + m;
return ret;
};
// 傳值捕捉本質(zhì)是?種拷?,并且被const修飾了
// mutable相當(dāng)于去掉const屬性,可以修改了
// 但是修改了不會影響外?被捕捉的值,因為是?種拷?
auto func7 = [=]()mutable
{
a++;
b++;
c++;
d++;
return a + b + c + d;
};
cout << func7() << endl;
cout << a << " " << b << " " << c << " " << d << endl;
return 0;
}三、lambda的應(yīng)用
學(xué)習(xí)lambda表達式之前,我們使用的可調(diào)用對象只有函數(shù)指針和仿函數(shù),它們的定義都相對麻煩,使用lambda表達式去定義可調(diào)用對象,就十分簡單方便了。
vector<pair<int, int>> v = { {1,2}, {3,4}, {8,3}, {5,1} };
//遇到這樣的場景,假如我們想要用多種排序規(guī)則進行排序,以前是需要寫不同的仿函數(shù)傳給sort
/*struct Compare_first
{
bool operator()(const pair<int, int>& p1, const pair<int, int>& p2)
{
return p1.first < p2.first;
}
};
struct Compare_second
{
bool operator()(const pair<int, int>& p1, const pair<int, int>& p2)
{
return p1.second < p2.second;
}
};
sort(v.begin(), v.end(), Compare_first());
sort(v.begin(), v.end(), Compare_second());*/
//有了lambda表達式后,就方便許多了
sort(v.begin(), v.end(), [](const pair<int, int>& p1, const pair<int, int>& p2) {return p1.first < p2.first; });
for (auto pa : v)
{
cout << pa.first << ":" << pa.second << " ";
}
cout << endl;
sort(v.begin(), v.end(), [](const pair<int, int>& p1, const pair<int, int>& p2) {return p1.second < p2.second; });
for (auto pa : v)
{
cout << pa.first << ":" << pa.second << " ";
}
cout << endl;
到此這篇關(guān)于C++簡單介紹lambda表達式的文章就介紹到這了,更多相關(guān)C++ lambda表達式內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C++17新特性編譯期 if 語句 (if constexpr)詳解
本文介紹了C++17引入的ifconstexpr關(guān)鍵字,通過解析其工作原理、底層機制和應(yīng)用場景,說明了其在模板元編程中的優(yōu)勢,本文將詳細、嚴(yán)謹(jǐn)?shù)仄饰銎涔ぷ髟砑昂诵膽?yīng)用場景,感興趣的朋友一起看看吧2026-04-04
C語言數(shù)據(jù)結(jié)構(gòu)之堆排序的優(yōu)化算法
堆排序Heap?Sort就是利用堆進行排序的方法,下面這篇文章主要給大家介紹了關(guān)于C語言數(shù)據(jù)結(jié)構(gòu)之堆排序的優(yōu)化算法的相關(guān)資料,文中通過實例代碼介紹的非常詳細,需要的朋友可以參考下2022-04-04
C++實現(xiàn)LeetCode(191.位1的個數(shù))
這篇文章主要介紹了C++實現(xiàn)LeetCode(191.位1的個數(shù)),本篇文章通過簡要的案例,講解了該項技術(shù)的了解與使用,以下就是詳細內(nèi)容,需要的朋友可以參考下2021-08-08

