国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

【C++】C++11語法 ~ lambda 表達(dá)式

這篇具有很好參考價(jià)值的文章主要介紹了【C++】C++11語法 ~ lambda 表達(dá)式。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

??歡迎來到C++專欄~~ lambda 表達(dá)式


  • (???(??? )??,我是Scort
  • 目前狀態(tài):大三非科班啃C++中
  • ??博客主頁:張小姐的貓~江湖背景
  • 快上車??,握好方向盤跟我有一起打天下嘞!
  • 送給自己的一句雞湯??:
  • ??真正的大師永遠(yuǎn)懷著一顆學(xué)徒的心
  • 作者水平很有限,如果發(fā)現(xiàn)錯(cuò)誤,可在評(píng)論區(qū)指正,感謝??
  • ????歡迎持續(xù)關(guān)注!
    【C++】C++11語法 ~ lambda 表達(dá)式,C++ ~ 登峰造極,c++,算法,開發(fā)語言

【C++】C++11語法 ~ lambda 表達(dá)式,C++ ~ 登峰造極,c++,算法,開發(fā)語言

【C++】C++11語法 ~ lambda 表達(dá)式,C++ ~ 登峰造極,c++,算法,開發(fā)語言

一. 概念

自 C++11 開始,C++ 有三種方式可以像函數(shù)使用的對(duì)象 / 類型:

函數(shù)指針
仿函數(shù)
Lambda 表達(dá)式

此處要注意:greater后面的括號(hào)是什么時(shí)候要加上?(容易混淆)

  • 首先我們要清楚,傳的是對(duì)象還是類型:傳的是對(duì)象就要加(),如果是類型就不用

【C++】C++11語法 ~ lambda 表達(dá)式,C++ ~ 登峰造極,c++,算法,開發(fā)語言
言歸正傳,lambda 表達(dá)式本質(zhì)上就是一個(gè)匿名函數(shù)

這里舉個(gè)例子:

struct Items
{
	string _name;  //名字
	double _price; //價(jià)格
	int _num;      //數(shù)量
};

如果要對(duì)若干對(duì)象分別按照價(jià)格和數(shù)量進(jìn)行升序、降序排序

可以使用 sort 函數(shù),但由于這里待排序的元素為自定義類,如果想按照我們的數(shù)據(jù)進(jìn)行排序,只能通過仿函數(shù)來實(shí)現(xiàn)了,那豈不是要實(shí)現(xiàn)6個(gè)仿函數(shù)?
有點(diǎn)麻煩了

struct ComparePriceLess//價(jià)格降序
{
	bool operator()(const Goods& g1, const Goods& g2)
	{
		return g1._price < g2._price;
	}
};
struct ComparePriceGreater//價(jià)格升序
{
	bool operator()(const Goods& g1, const Goods& g2)
	{
		return g1._price > g2._price;
	}
};
int main()
{
	vector<Goods> v = { { "蘋果", 2.1, 300 }, { "香蕉", 3.3, 100 }, { "橙子", 2.2, 1000 }, { "菠蘿", 1.5, 1 } };
	sort(v.begin(), v.end(), ComparePriceLess());    //價(jià)格升序
	sort(v.begin(), v.end(), ComparePriceGreater()); //價(jià)格降序
	return 0;
}

為此lambda 表達(dá)式就橫空出世了

二. 語法

lambda 表達(dá)式定義:

[capture-list] (parameters) mutable -> return-type { statement }

表達(dá)式各部分說明:

  • [capture-list] : 捕捉列表,該列表總是出現(xiàn)在lambda函數(shù)的開始位置,編譯器根據(jù)[]來判斷接下來的代碼是否為lambda函數(shù),捕捉列表能夠捕捉上下文中的變量供lambda函數(shù)使用
  • (parameters)參數(shù)列表。與普通函數(shù)的參數(shù)列表一致,如果不需要參數(shù)傳遞,則可以連同()一起省略(無參可以省略
  • mutable:默認(rèn)情況下,lambda函數(shù)總是一個(gè)const函數(shù),mutable可以取消其常量
    性。使用該修飾符時(shí),參數(shù)列表不可省略(即使參數(shù)為空)
  • ->returntype返回值類型。用追蹤返回類型形式聲明函數(shù)的返回值類型,沒有返回值時(shí)此部分可省略。返回值類型明確情況下,也可省略,由編譯器對(duì)返回類型進(jìn)行推導(dǎo)
  • {statement}函數(shù)體。在該函數(shù)體內(nèi),除了可以使用其參數(shù)外,還可以使用所有捕獲到的變量

除了捕獲列表,Lambda表達(dá)式的其它地方其實(shí)和普通的函數(shù)基本一樣,lambda 參數(shù)列表和返回值類型都是可有可無的,但捕捉列表和函數(shù)體是不可省略的,因此最簡(jiǎn)單的lambda函數(shù)如下:

int main()
{
	[]{}; //最簡(jiǎn)單的lambda表達(dá)式
	return 0;
}

再舉個(gè)函數(shù)相加的例子:

int main()
{
	//兩個(gè)函數(shù)相加
	auto add1 = [] (int a, int b)->int{return a + b; };
	cout << add1(1, 2) << endl;

	//省略返回值
	auto add2 = [](int a, int b){return a + b; };
	cout << add1(1, 2) << endl;

	return 0;
}

如果我們要不傳參數(shù),該怎么樣實(shí)現(xiàn)呢?

三. 捕獲方式

Lambda 表達(dá)式最基本的兩種捕獲方式是:按值捕獲和按引用捕獲

  • [var]:值傳遞捕捉變量var
  • [=]:值傳遞捕獲所有父作用域中的變量(成員函數(shù)包括this指針)
  • [&var]:引用傳遞捕捉變量var
  • [&]:引用傳遞捕捉所有父作用域中的變量(成員函數(shù)包括this指針)

注意:

  1. 1??父作用域要包含lambda函數(shù)語句(一般指的是當(dāng)前所在的函數(shù)(棧幀)
  2. 2??語法上捕捉可由多個(gè)捕捉項(xiàng)組成,并以逗號(hào)分割(就是可以混合著來)
  //混合捕捉:a是引用捕捉,其他都是傳值捕捉
  auto f1 = [=, &a]() {
  	cout << a << b << c << d << e << endl;
  };

  f1();
  1. 3??捕捉列表不允許變量重復(fù)傳遞,否則就會(huì)導(dǎo)致編譯錯(cuò)誤
  2. 4??在塊作用域以外的lambda函數(shù)捕捉列表必須為空
  3. 5??在塊作用域中的lambda函數(shù)僅能捕捉父作用域中局部變量,捕捉任何非此作用域或者非局部變量都 會(huì)導(dǎo)致編譯報(bào)錯(cuò)。

來個(gè)例題:此處的f可以++嗎?

int f = 0;
int main()
{
	int a, b, c, d, e;
	a = b = c = d = e = 1;

	//混合捕捉:a是引用捕捉,其他都是傳值捕捉
	auto f1 = [=, &a]() {
		f++;
		cout << a << b << c << d << e << endl;
	};

	f1();
	return 0;
}

f為什么可以呢?

  • 因?yàn)?code>f是全局變量不存在于棧幀里,存在于靜態(tài)區(qū),哪個(gè)位置都可以用它!

復(fù)習(xí)一下:
對(duì)象的作用域和存儲(chǔ)區(qū)域要分清楚:

  • 生命周期是和存儲(chǔ)的區(qū)域有關(guān)系
  • 作用域(編譯器編譯,用的地方能否找到) 局部 —> 全局

??相互賦值

lambda表達(dá)式之間不能相互賦值,就算是兩個(gè)一模一樣的也不行

lambda 表達(dá)式會(huì)被處理為函數(shù)對(duì)象,該函數(shù)對(duì)象對(duì)應(yīng)的類名叫做<lambda_uuid>

類名中的uuid叫做通用唯一識(shí)別碼,簡(jiǎn)單來說就是通過算法生成的一串字符串,它具有隨機(jī)性和不重復(fù)性,保證在當(dāng)前程序中每次生成不同的 uuid,因?yàn)?lambda 表達(dá)式底層的類名包含 uuid,這就保證了每個(gè) lambda 表達(dá)式底層類名都是唯一的!

void (*PF)();
int main()
{
	 auto f1 = []{cout << "hello world" << endl; };
	 auto f2 = []{cout << "hello world" << endl; };
	    
	 f1 = f2;   // 編譯失敗--->提示找不到operator=()
	            //實(shí)例化后的兩個(gè)lambda類型,類型不一樣
	 auto f3(f2);
	 f3();
	 // 可以將lambda表達(dá)式賦值給相同類型的函數(shù)指針
	 PF = f2;
	 PF();
	 return 0;
}

但是lambda表達(dá)式賦值給相同類型的函數(shù)指針

就是在我們看來是一樣的,但是其底層大有不同!

四. 底層實(shí)現(xiàn)

實(shí)際在底層編譯器對(duì)于lambda表達(dá)式的處理方式,完全就是按照函數(shù)對(duì)象的方式處理的,就是對(duì)()進(jìn)行了重載

class Add
{
public:
	Add(int base)
		:_base(base)
	{}
	int operator()(int num)
	{
		return _base + num;
	}
private:
	int _base;
};
int main()
{
	int base = 1;

	//函數(shù)對(duì)象
	Add add1(base);
	add1(1000);

	//lambda表達(dá)式
	auto add2 = [base](int num)->int
	{
		return base + num;
	};
	add2(1000);
	return 0;
}

對(duì)反匯編進(jìn)行觀察:

【C++】C++11語法 ~ lambda 表達(dá)式,C++ ~ 登峰造極,c++,算法,開發(fā)語言

當(dāng)創(chuàng)建add對(duì)象的時(shí)候是構(gòu)造函數(shù),使用add對(duì)象的時(shí)候就是會(huì)調(diào)用 Add 類的 () 運(yùn)算符重載函數(shù)

【C++】C++11語法 ~ lambda 表達(dá)式,C++ ~ 登峰造極,c++,算法,開發(fā)語言

lambda 表達(dá)式同樣如此:會(huì)調(diào)用 <lambda_uuid> 類的構(gòu)造函數(shù),在使用add2對(duì)象時(shí),會(huì)調(diào)用<lambda_uuid>類的 ()運(yùn)算符重載函數(shù)

其本質(zhì)就是:lambda表達(dá)式在底層被轉(zhuǎn)換成了仿函數(shù)

當(dāng)我們定義一個(gè)lambda表達(dá)式后,編譯器會(huì)自動(dòng)生成一個(gè)類,在該類中對(duì) () 運(yùn)算符進(jìn)行重載,實(shí)際 lambda 函數(shù)體的實(shí)現(xiàn)就是這個(gè)仿函數(shù) operator() 的實(shí)現(xiàn),在調(diào)用 lambda 表達(dá)式時(shí),參數(shù)列表和捕獲列表的參數(shù),最終都傳遞給了仿函數(shù)的 operator()

五. mutable(作用不大)

在實(shí)際使用中,比如實(shí)現(xiàn)一個(gè)交換函數(shù),我們用 lambda 表達(dá)式實(shí)現(xiàn):

int main()
{
	auto swap2 = [x, y]() 
	{
		int tmp = x;
		x = y;
		y = tmp;
	};
	swap2();
	return 0;
}

這里我們發(fā)現(xiàn)是傳值傳參!果然編譯不通過,因?yàn)閭髦挡东@到的變量默認(rèn)是不可修改的(const):

如果要取消其常量屬性,就需要在 lambda 表達(dá)式中加上 mutable 像這樣:

	auto swap2 = [x, y]() mutable    //改變的是形參,實(shí)參無影響,所以沒用
	{
		int tmp = x;
		x = y;
		y = tmp;
	};

但是捕捉列表是傳值捕捉過來的,不影響外面的實(shí)參;所以這種方法無法完成交換功能

【C++】C++11語法 ~ lambda 表達(dá)式,C++ ~ 登峰造極,c++,算法,開發(fā)語言

??寫在最后

【C++】C++11語法 ~ lambda 表達(dá)式,C++ ~ 登峰造極,c++,算法,開發(fā)語言文章來源地址http://www.zghlxwxcb.cn/news/detail-809187.html

到了這里,關(guān)于【C++】C++11語法 ~ lambda 表達(dá)式的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • 【C++進(jìn)階】C++11(下)可變參數(shù)模板&lambda表達(dá)式&包裝器

    【C++進(jìn)階】C++11(下)可變參數(shù)模板&lambda表達(dá)式&包裝器

    我們緊接著上一節(jié)的講解來進(jìn)行 C++11的新特性可變參數(shù)模板能夠讓您創(chuàng)建可以接受可變參數(shù)的函數(shù)模板和類模板,相比C++98/03,類模版和函數(shù)模版中只能含固定數(shù)量的模版參數(shù),可變模版參數(shù)無疑是一個(gè)巨大的改進(jìn)。然而由于可變模版參數(shù)比較抽象,使用起來需要一定的技巧

    2024年04月11日
    瀏覽(31)
  • 【C++】C++11右值引用|新增默認(rèn)成員函數(shù)|可變參數(shù)模版|lambda表達(dá)式

    【C++】C++11右值引用|新增默認(rèn)成員函數(shù)|可變參數(shù)模版|lambda表達(dá)式

    在C++11之前,我們只有引用的概念,沒有接觸到所謂的左值引用或者是右值引用這種概念,從C++11開始,增加了右值引用的概念,那么現(xiàn)在我們將對(duì)引用進(jìn)行一個(gè)概念上的區(qū)分。在此之前我們所說的引用都是左值引用,對(duì)于左值引用相關(guān)的內(nèi)容,可以去看一看博主之前寫的文章

    2024年02月15日
    瀏覽(33)
  • Lambda表達(dá)式:簡(jiǎn)介、語法和用法

    Lambda表達(dá)式:簡(jiǎn)介、語法和用法

    Lambda表達(dá)式是Java 8中引入的一個(gè)重要特性,它允許開發(fā)者以更加簡(jiǎn)潔的方式編寫函數(shù)式代碼。在本文中,我們將深入探討Lambda表達(dá)式的概念、語法和用法,并為每個(gè)實(shí)例提供代碼演示,同時(shí)對(duì)比與傳統(tǒng)方法的區(qū)別和優(yōu)勢(shì)。 Lambda表達(dá)式是一種匿名函數(shù),它主要用于表示簡(jiǎn)單的行

    2023年04月19日
    瀏覽(34)
  • C++11:lambda表達(dá)式

    C++11:lambda表達(dá)式

    lambda表達(dá)式實(shí)際上是一個(gè)匿名類的成員函數(shù),該類由編譯器為lambda創(chuàng)建,該函數(shù)被隱式地定義為內(nèi)聯(lián)。因此,調(diào)用lambda表達(dá)式相當(dāng)于直接調(diào)用它的operator()函數(shù),這個(gè)函數(shù)可以被編譯器內(nèi)聯(lián)優(yōu)化(建議)。 例如快速排序算法,STL允許用戶自定義比較方式,在C++11之前,通常使用

    2024年02月14日
    瀏覽(17)
  • C++11 lambda表達(dá)式

    C++11 lambda表達(dá)式

    lambda表達(dá)式是C++11或者更新版本的一個(gè) 語法糖 ,本身不是C++開發(fā)的。但是因其便利,很值得我們學(xué)習(xí)和使用。lambda有很多叫法,有l(wèi)ambda表達(dá)式、lambda函數(shù)、匿名函數(shù),本文中為了方便表述統(tǒng)一用 lambda表達(dá)式 進(jìn)行敘述。 在C++中,為了實(shí)現(xiàn)泛型編程,在一個(gè)類中,我們難免遇到

    2024年02月08日
    瀏覽(32)
  • 【 C++11 】lambda表達(dá)式

    【 C++11 】lambda表達(dá)式

    目錄 1、lambda表達(dá)式的引入 2、lambda表達(dá)式 ????????lambda表達(dá)式的語法 ????????lambda表達(dá)式捕捉列表說明 ????????使用lambda表達(dá)式排序自定義類型 ????????lambda表達(dá)式的底層原理 1、lambda表達(dá)式的引入 在C++98中,如果想要對(duì)一個(gè)數(shù)據(jù)集合中的元素進(jìn)行排序,可以

    2024年02月08日
    瀏覽(23)
  • C++11_lambda表達(dá)式

    C++11_lambda表達(dá)式

    lambda表達(dá)式是C++11新引入的功能,它的用法與我們之前學(xué)過的C++語法有些不同。 [capture-list] (parameters) mutable - return-type { statement } [capture-list] : 捕捉列表,該列表總是出現(xiàn)在lambda函數(shù)的開始位置,編譯器根據(jù)[]來 判斷接下來的代碼是否為lambda函數(shù),捕捉列表能夠捕捉上下文中的

    2024年02月02日
    瀏覽(22)
  • C++11的lambda表達(dá)式

    C++11的lambda表達(dá)式

    Lambda表達(dá)式是一種匿名函數(shù),允許我們?cè)诓宦暶鞣椒ǖ那闆r下,直接定義函數(shù)。它是函數(shù)式編程的一種重要特性,常用于簡(jiǎn)化代碼、優(yōu)化程序結(jié)構(gòu)和增強(qiáng)代碼可讀性。 lambda表達(dá)式的語法非常簡(jiǎn)單,具體定義如下: 舉例: [ captures ] —— 捕獲列表,它可以捕獲當(dāng)前函數(shù)作用域

    2024年02月03日
    瀏覽(16)
  • 【C++11】lambda表達(dá)式 包裝器

    【C++11】lambda表達(dá)式 包裝器

    在C++98中,如果想要對(duì)一個(gè)數(shù)據(jù)集合中的元素進(jìn)行排序,可以使用std::sort方法: 如果待排序元素為自定義類型,需要用戶定義排序時(shí)的比較規(guī)則: 如果仿函數(shù)命名比較規(guī)范的話,像上面的命名方式的話那還好,如果遇到了像cmp1 cmp2 cmp3…這種命名方式而且還沒有注釋的話可以

    2024年02月12日
    瀏覽(17)
  • C++11新特性lambda 表達(dá)式

    C++11新特性lambda 表達(dá)式

    Lambda 表達(dá)式的基本語法是:[] (參數(shù)列表) - 返回值類型 {函數(shù)體}。 方括號(hào)([])表示捕獲列表,用來指定在 lambda 表達(dá)式中可以訪問的外部變量。 參數(shù)列表和返回值類型與普通函數(shù)的參數(shù)列表和返回值類型相同。 函數(shù)體則是實(shí)際的代碼邏輯。 不接受任何參數(shù):[] { 函數(shù)體 } 接受

    2024年02月14日
    瀏覽(31)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包