C++lambda表達(dá)式使用介紹
前言
C++98中的一個(gè)例子。
#include <iostream> #include <vector> #include <string> #include <algorithm> using namespace std; struct Goods { string _name; float _price; int _evaluate; Goods(const char* str, double price, int evaluate) :_name(str) , _price(price) , _evaluate(evaluate) {} }; struct PriceGreater { bool operator()(const Goods& g1, const Goods& g2) { return g1._price < g2._price; } }; struct PriceLess { bool operator()(const Goods& g1, const Goods& g2) { return g1._price > g2._price; } }; int main(void) { vector<Goods> v{ {"蘋果", 3.15, 5}, {"香蕉", 4.2, 3}, {"西瓜", 2.8, 4} }; sort(v.begin(), v.end(), PriceLess()); //按價(jià)格的降序比較 sort(v.begin(), v.end(), PriceGreater()); //按價(jià)格的升序比較 return 0; }
如果待排序的元素是自定義類型,使用sort算法排序時(shí),需要用戶去定義仿函數(shù)類。如果每次比較邏輯不同,就需要實(shí)現(xiàn)不同仿函數(shù)類,這是極其不方便的。所以c++11語(yǔ)法增加了Lambda表達(dá)式。
lambda表達(dá)式格式
lambda表達(dá)式的格式
[捕捉列表](參數(shù)列表)mutable->返回值類型{ 語(yǔ)句部分 };
其中參數(shù)列表、返回值類型是可選的,捕捉列表、函數(shù)體可以為空。
先來(lái)看一個(gè)較為簡(jiǎn)單的lamda表達(dá)式
int main(void) { auto add = [](int a, int b)->int {return a + b; }; cout << add(1, 2) << endl; return 0; }
mutable可以省略,暫時(shí)不考慮。
- 捕捉列表,捕捉列表的
[]
是千萬(wàn)不能省略的,編譯器會(huì)根據(jù)[]
判斷該表達(dá)式是否為lambda表達(dá)式,捕捉列表能夠捕捉上下文的變量提供給lambda表達(dá)式使用。 - 參數(shù)列表,就和普通的函數(shù)傳參是一樣的,如果不需要參數(shù),那么可以連同
()
一起省略 - mutable:默認(rèn)情況下,lambda表達(dá)式參數(shù)列表和捕捉列表被修飾成const屬性,而mutable的作用就是取消它的const屬性。如果使用了mutable參數(shù)一定不能省略,如果參數(shù)為空,那么需要保留
()
。 - ->返回值類型。返回值類型明確或沒(méi)有返回值的情況下,該部分可省略,編譯器會(huì)對(duì)返回值類型進(jìn)行推導(dǎo)。
- 語(yǔ)句部分。和不同函數(shù)的函數(shù)體內(nèi)語(yǔ)句部分是一樣的含義,函數(shù)體內(nèi)不僅可以使用它的參數(shù),還可以使用所有捕獲到的變量。
所以最簡(jiǎn)單的lambda表達(dá)式應(yīng)該是[]{}
lambda表達(dá)式又被稱為匿名函數(shù),無(wú)法被直接調(diào)用,它的底層其實(shí)也是仿函數(shù)類。需要借助auto將表達(dá)式賦值給一個(gè)變量。
一些語(yǔ)法
lambda表達(dá)式的捕捉列表不能捕捉全局變量/靜態(tài)變量
//lambda表達(dá)式的捕捉列表不能捕捉全局變量 / 靜態(tài)變量 int c = 0, d = 0; auto func1 = [c, d]() {}; int main(void) { static int a = 0; static int b = 0; auto func1 = [a, b]() {}; return 0; }
如果想要改變參數(shù)/捕捉列表,那么就需要加mutable取消const
屬性
//交換兩個(gè)變量的值,方式一: int a = 1, b = 2; auto swap1 = [](int& x, int& y)mutable {int tmp = x; x = y; y = tmp; }; swap1(a, b);
捕捉列表描述了上下文中那些數(shù)據(jù)可以被lambda使用,以及使用的方式傳值還是傳引用。
[var]:表示值傳遞方式捕捉變量var
[=]:表示值傳遞方式捕獲所有父作用域中的變量(包括this)
[&var]:表示引用傳遞捕捉變量var
[&]:表示引用傳遞捕捉所有父作用域中的變量(包括this)
[this]:表示值傳遞方式捕捉當(dāng)前的this指
默認(rèn)情況下,使用值傳遞的方式,捕捉到的變量被修飾成const
屬性;引用傳遞方式?jīng)]有被修飾。
函數(shù)體內(nèi)使用捕捉到變量,實(shí)際上是捕捉變量的一份拷貝,所以需要對(duì)捕捉變量進(jìn)行修改時(shí),不能使用值傳遞的方式。
//交換兩個(gè)變量的值,方式二: auto swap3 = [&c, &d](){int tmp = c; c = d; d = tmp; }; swap3();
【捕捉列表注意】
同一個(gè)變量不能被同一種傳遞方式多次捕捉。捕捉的范圍:父作用域中所有的非靜態(tài)局部變量。
走進(jìn)底層
調(diào)用lambda表達(dá)式的時(shí)候,先把它賦值給auto類型的對(duì)象,然后再使用()
調(diào)用。
auto的作用是自動(dòng)推導(dǎo)右邊表達(dá)式的類型,那么lambda表達(dá)式的類型是什么?
add是一個(gè)類對(duì)象,類名為<lambda_+uuid>
,點(diǎn)擊此處了解uuid。
增加一個(gè)lambda表達(dá)式的調(diào)用
add(1, 2);
轉(zhuǎn)到反匯編,發(fā)現(xiàn)它的類里重載了()
,調(diào)用lambda表達(dá)式的底層是去調(diào)用類成員方法operator()
。
可見(jiàn)lambda表達(dá)式的底層就是仿函數(shù)類,所以它的調(diào)用方法也和仿函數(shù)是一樣的。
不同的lambda表達(dá)式生成的類,是不同的類。一個(gè)lambda表達(dá)式再寫一份,生成的類也是不同的,可以認(rèn)為一個(gè)lambda表達(dá)式語(yǔ)句生成一個(gè)自己唯一的類。
//lambda表達(dá)式格式 auto add = [](int a, int b)->int {return a + b; }; add(1, 2); auto add2 = [](int a, int b)->int {return a + b; }; add2(1, 2);
因此要注意,lambda表達(dá)式之間不能相互賦值。
到此這篇關(guān)于C++lambda表達(dá)式使用介紹的文章就介紹到這了,更多相關(guān)C++lambda內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C語(yǔ)言棧順序結(jié)構(gòu)實(shí)現(xiàn)代碼
一個(gè)能夠自動(dòng)擴(kuò)容的順序結(jié)構(gòu)的棧 ArrStack 實(shí)例 (GCC編譯),有需要的朋友可以參考一下2013-10-10Qt槽函數(shù)會(huì)被執(zhí)行多次的問(wèn)題原因及解決方法
本文主要介紹了Qt槽函數(shù)會(huì)被執(zhí)行多次的問(wèn)題原因及解決方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2023-01-01C++中template方法undefined reference to的問(wèn)題解決
Undefined reference to 錯(cuò)誤:這類錯(cuò)誤是在連接過(guò)程中出現(xiàn)的,本文就來(lái)介紹一下C++中template方法undefined reference to的問(wèn)題解決,具有一定的參考價(jià)值,感興趣的可以了解一下2024-03-03window調(diào)用api列出當(dāng)前所有進(jìn)程示例
這篇文章主要介紹了window調(diào)用api列出當(dāng)前所有進(jìn)程示例,需要的朋友可以參考下2014-04-04C++中可正確獲取UTF-8字符長(zhǎng)度的函數(shù)分享
這篇文章主要介紹了C++中可正確獲取UTF-8字符長(zhǎng)度的函數(shù)分享,需要的朋友可以參考下2014-08-08C++多線程實(shí)現(xiàn)TCP服務(wù)器端同時(shí)和多個(gè)客戶端通信
通訊建立后首先由服務(wù)器端發(fā)送消息,客戶端接收消息;接著客戶端發(fā)送消息,服務(wù)器端接收消息,實(shí)現(xiàn)交互發(fā)送消息。本文主要介紹了C++多線程實(shí)現(xiàn)TCP服務(wù)器端同時(shí)和多個(gè)客戶端通信,感興趣的可以了解一下2021-05-05C++ 中隨機(jī)函數(shù)random函數(shù)的使用方法
這篇文章主要介紹了C++ 中隨機(jī)函數(shù)random函數(shù)的使用方法的相關(guān)資料,希望通過(guò)本文能幫助到大家,需要的朋友可以參考下2017-09-09