【C++11】——lambda表達(dá)式-創(chuàng)新互聯(lián)

成都創(chuàng)新互聯(lián)于2013年創(chuàng)立,先為汝南等服務(wù)建站,汝南等地企業(yè),進行企業(yè)商務(wù)咨詢服務(wù)。為汝南企業(yè)網(wǎng)站制作PC+手機+微官網(wǎng)三網(wǎng)同步一站式服務(wù)解決您的所有建站問題。

目錄

一、lambda表達(dá)式的簡介

二、lambda表達(dá)式的基本語法

三、lambda表達(dá)式的使用方法

四、lambda表達(dá)式的底層原理


一、lambda表達(dá)式的簡介

lambda表達(dá)式就類似于仿函數(shù),相比仿函數(shù)要更加的簡潔,我們看一下下面的代碼:

//商品類
struct Goods
{
    string _name; ?// 名字
    double _price; // 價格
    int _evaluate; // 評價
};

在給定的商品類中,如果我們想要通過名字、價格和評價來給商品進行升序或降序。在沒有l(wèi)ambda表達(dá)式的時候,通過仿函數(shù)就可以實現(xiàn),代碼如下:

//按價格的升序
struct ComparePriceLess
{
	bool operator()(const Goods& g1, const Goods& g2)
	{
		return g1._price< g2._price;
	}
};

//按價格降序
struct ComparePriceGreater
{
	bool operator()(const Goods& g1, const Goods& g2)
	{
		return g1._price >g2._price;
	}
};

int main()
{
	vectorv = { { "蘋果", 2.1, 300 }, { "香蕉", 3.3, 100 }, { "橙子", 2.2, 1000 }, { "菠蘿", 1.5, 1 } };
	sort(v.begin(), v.end(), ComparePriceLess());    //按價格升序排序
	sort(v.begin(), v.end(), ComparePriceGreater()); //按價格降序排序
	return 0;
}

顯然這樣寫是沒有什么問題,但是,如果你寫的仿函數(shù)在取名的時候不是很貼切,導(dǎo)致他人看你寫的仿函數(shù)的時候,有可能看不懂,我們來看看lambda表達(dá)式寫出來是什么樣子的;

int main()
{
	vectorv = { { "蘋果", 2.1, 300 }, { "香蕉", 3.3, 100 }, { "橙子", 2.2, 1000 }, { "菠蘿", 1.5, 1 } };
	sort(v.begin(), v.end(), [](const Goods& g1, const Goods& g2)
	{
		return g1._price< g2._price; 
	}); //按價格升序排序

	sort(v.begin(), v.end(), [](const Goods& g1, const Goods& g2)
	{
		return g1._price >g2._price;
	}); //按價格降序排序

	return 0;
}

這樣一來,每次調(diào)用sort函數(shù)時只需要傳入一個lambda表達(dá)式指明比較方式即可,閱讀代碼的人一看到lambda表達(dá)式就知道本次排序的比較方式是怎樣的,提高了代碼的可讀性。?

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

lambda函數(shù)的參數(shù)列表和返回值類型都是可選部分,但捕捉列表和函數(shù)體是不可省略的,因此最簡單的lambda函數(shù)如下:?

int main()
{
    //最簡單的lambda表達(dá)式,該lambda表達(dá)式?jīng)]有任何意義
	[]{}; 

	return 0;
}

捕獲列表說明:

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

注意:
  1. 父作用域指的是包含lambda函數(shù)的語句塊
  2. 語法上捕捉列表可由多個捕捉項組成,并以逗號分割。比如:[=, &a, &b],以引用傳遞的方式捕捉變量a和b,值傳遞方式捕捉其他所有變量 ;[&,a, this]:值傳遞方式捕捉變量a和this,引用方式捕捉其他變量;
  3. 捕捉列表不允許變量重復(fù)傳遞,否則就會導(dǎo)致編譯錯誤。 比如:[=, a]:=已經(jīng)以值傳遞方式捕捉了所有變量,捕捉a重復(fù)
  4. 在塊作用域以外的lambda函數(shù)捕捉列表必須為空。
  5. 在塊作用域中的lambda函數(shù)僅能捕捉父作用域中局部變量,捕捉任何非此作用域或者非局部變量都會導(dǎo)致編譯報錯。
  6. lambda表達(dá)式之間不能相互賦值,即使看起來類型相同。
三、lambda表達(dá)式的使用方法

使用lambda表達(dá)式進行兩數(shù)的交換

int main()
{
	int a = 10, b = 20;
    //這里的“->void”也是可以省略的
	auto Swap = [](int& x, int& y)->void{
		int tmp = x;
		x = y;
		y = tmp;
	};

	Swap(a, b); 

	return 0;
}

使用傳值捕捉所有

int main()
{
	int a = 10, b = 20;
	//傳值捕捉所有
	auto Swap = [=]()mutable {
		int tmp = a;
		a = b;
		b = tmp;
	};

	Swap();

	//傳值捕捉a和b
	auto Swap2 = [a, b]()mutable {
		int tmp = a;
		a = b;
		b = tmp;
	};
	Swap2();

	return 0;
}

這里需要注意,在以傳值捕捉的時候,因為lambda表達(dá)式總是一個const函數(shù),mutable可以取消其常量性,此時的圓括號也不可以省略

以引用捕捉?

int main()
{
	int a = 10, b = 20;
	//以引用捕捉所有
	auto Swap = [&]{
		int tmp = a;
		a = b;
		b = tmp;
	};

	Swap();

	//以引用捕捉a和b
	auto Swap2 = [&a, &b]{
		int tmp = a;
		a = b;
		b = tmp;
	};
	Swap2();

	//以引用捕捉a、以傳值捕捉b
	auto Swap3 = [&a, b]()mutable {
		int tmp = a;
		a = b;
		b = tmp;
	};
	Swap3();

	return 0;
}

lambda表達(dá)式之間不能相互賦值,即使看起來類型相同

void (*PF)();
int main()
{
	auto f1 = [] {cout<< "hello world"<< endl; };
	auto f2 = [] {cout<< "hello world"<< endl; };

	//f1 = f2; ? // 編譯失敗--->提示找不到operator=()

	// 但允許使用一個lambda表達(dá)式拷貝構(gòu)造一個新的副本
	auto f3(f2);
	f3();

	// 可以將lambda表達(dá)式賦值給相同類型的函數(shù)指針
	PF = f2;
	PF();

	return 0;
}
四、lambda表達(dá)式的底層原理

函數(shù)對象,又稱為仿函數(shù),即可以想函數(shù)一樣使用的對象,就是在類中重載了operator()運算符的類對象。

class Rate
{
public:
	Rate(double rate) : _rate(rate)
	{}

	double operator()(double money, int year)
	{
		return money * _rate * year;
	}

private:
	double _rate;
};

int main()
{
	// 函數(shù)對象
	double rate = 0.49;
	Rate r1(rate);
	r1(10000, 2);

	// lamber
	auto r2 = [=](double monty, int year)->double {return monty * rate * year;};
	r2(10000, 2);

	return 0;
}
函數(shù)對象將rate作為其成員變量,在定義對象時給出初始值即可,lambda表達(dá)式通過捕獲列表可以直接將該變量捕獲到。

lambda表達(dá)式底層的處理方式和仿函數(shù)是一樣的,在VS下,lambda表達(dá)式在底層會被處理為函數(shù)對象,該函數(shù)對象對應(yīng)的類名叫做。就算是兩個相同的lambda表達(dá)式,它們的uuid也是不同的;

你是否還在尋找穩(wěn)定的海外服務(wù)器提供商?創(chuàng)新互聯(lián)www.cdcxhl.cn海外機房具備T級流量清洗系統(tǒng)配攻擊溯源,準(zhǔn)確流量調(diào)度確保服務(wù)器高可用性,企業(yè)級服務(wù)器適合批量采購,新人活動首月15元起,快前往官網(wǎng)查看詳情吧

當(dāng)前標(biāo)題:【C++11】——lambda表達(dá)式-創(chuàng)新互聯(lián)
網(wǎng)頁地址:http://muchs.cn/article10/cdgogo.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供品牌網(wǎng)站制作、網(wǎng)頁設(shè)計公司、ChatGPT、虛擬主機、電子商務(wù)標(biāo)簽優(yōu)化

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

手機網(wǎng)站建設(shè)