最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C++11中的lambda表達(dá)式與包裝器

 更新時(shí)間:2025年07月18日 10:01:03   作者:古月-一個(gè)C++方向的小白  
C++11中l(wèi)ambda是匿名函數(shù),可捕獲外部變量,std::function統(tǒng)一存儲可調(diào)用對象,bind調(diào)整參數(shù)順序和數(shù)量,兩者簡化了函數(shù)對象的使用,本文給大家介紹C++11中的lambda表達(dá)式與包裝器,感興趣的朋友一起看看吧

lambda語法

lambda 表達(dá)式本質(zhì)是?個(gè)匿名函數(shù)對象,跟普通函數(shù)不同的是他可以定義在函數(shù)內(nèi)部。
lambda 表達(dá)式語法使?層??沒有類型,所以我們?般是?auto或者模板參數(shù)定義的對象去接收 lambda 對象
lambda表達(dá)式的格式: [capture-list] (parameters)-> return type {function boby }

  1. [capture-list] : 捕捉列表,該列表總是出現(xiàn)在 lambda 函數(shù)的開始位置,編譯器根據(jù)[]來判斷接下來的代碼是否為 lambda 函數(shù),捕捉列表能夠捕捉上?中的變量供 lambda 函數(shù)使用,捕捉列表可以傳值和傳引?捕捉。捕捉列表為空也不能省略。(捕捉列表只能是已經(jīng)定義的)
  2. (parameters) :參數(shù)列表,與普通函數(shù)的參數(shù)列表功能類似,如果不需要參數(shù)傳遞,則可以連同()?起省略
  3. ->return type :返回值類型,?追蹤返回類型形式聲明函數(shù)的返回值類型,沒有返回值時(shí)此部分可省略。?般返回值類型明確情況下,也可省略,由編譯器對返回類型進(jìn)?推導(dǎo)。
  4. {function boby} :函數(shù)體,函數(shù)體內(nèi)的實(shí)現(xiàn)跟普通函數(shù)完全類似,在該函數(shù)體內(nèi),除了可以使?其參數(shù)外,還可以使?所有捕獲到的變量,函數(shù)體為空也不能省略。
auto add1 = [](int x, int y)->int {return x + y; };
cout << add1(1, 2) << endl;
// 1、捕捉為空也不能省略
// 2、參數(shù)為空可以省略
// 3、返回值可以省略,可以通過返回對象?動(dòng)推導(dǎo)
// 4、函數(shù)題不能省略
auto func1 = []
{
	cout << "hello bit" << endl;
	return 0;
};

捕捉列表

  1. lambda 表達(dá)式中默認(rèn)只能? lambda 函數(shù)體和參數(shù)中的變量,如果想用外層作?域中的變量就需要進(jìn)?捕捉
  2. 第?種捕捉?式是在捕捉列表中顯?的傳值捕捉和傳引?捕捉,捕捉的多個(gè)變量?逗號分割。[x,y, &z] 表?x和y值捕捉,z引?捕捉。
  3. 第?種捕捉?式是在捕捉列表中隱式捕捉,我們在捕捉列表寫?個(gè)=表?隱式值捕捉,在捕捉列表寫?個(gè)&表?隱式引?捕捉,這樣我們 lambda 表達(dá)式中?了那些變量,編譯器就會?動(dòng)捕捉那些變量
  4. 第三種捕捉?式是在捕捉列表中混合使?隱式捕捉和顯?捕捉。[=, &x]表?其他變量隱式值捕捉,x引?捕捉;[&, x, y]表?其他變量引?捕捉,x和y值捕捉。當(dāng)使用混合捕捉時(shí),第?個(gè)元素必須是&或=,并且&混合捕捉時(shí),后?的捕捉變量必須是值捕捉,同理=混合捕捉時(shí),后面的捕捉變量必須是引用捕捉。
  5. lambda 表達(dá)式如果在函數(shù)局部域中,他可以捕捉 lambda 位置之前定義的變量,不能捕捉靜態(tài)局部變量和全局變量,靜態(tài)局部變量和全局變量也不需要捕捉, lambda 表達(dá)式中可以直接使?。這也意味著 lambda 表達(dá)式如果定義在全局位置,捕捉列表必須為空。(但是一般都是將lambda定義在局部區(qū)域
  6. 默認(rèn)情況下, lambda 捕捉列表是被const修飾的,也就是說傳值捕捉的過來的對象不能修改,mutable加在參數(shù)列表的后?可以取消其常量性,也就說使?該修飾符后,傳值捕捉的對象就可以修改了,但是修改還是形參對象,不會影響實(shí)參。使?該修飾符后,參數(shù)列表不可省略(即使參數(shù)為空)。
auto func1 = [a, &b]
{
	// 值捕捉的變量不能修改,引?捕捉的變量可以修改
	//a++;
	b++;
	int ret = a + b;
	return ret;
};
auto func2 = [=]
{
	int ret = a + b + c;
	return ret;
};
auto func6 = []
{
	int ret = x + m;
	return ret;
};
auto func4 = [&, a, b]
{
	//a++;
	//b++;
	c++;
	d++;
	return a + b + c + d;
};
auto func5 = [=, &a, &b]
{
	a++;
	b++;
	/*c++;
	d++;*/
	return a + b + c + d;
};
auto func7 = [=]()mutable
{
	a++;
	b++;
	c++;
};

但如果lambda是寫在類里面的,那么lambda是不能夠捕獲私有成員變量的,也是不能直接使用的,如果想使用需要捕獲this指針

class A
{
public:
	void f()
	{
		auto add1 = [this](int a,int b){return a + b + _a1 + _a2};
	}
private:
int _a1 = 1;
int _a2 = 2;
};

lambda的應(yīng)用

在學(xué)習(xí) lambda 表達(dá)式之前,可調(diào)用對象只有函數(shù)指針和仿函數(shù)對象,函數(shù)指針的類型定義起來比較麻煩,仿函數(shù)要定義?個(gè)類,相對會比較麻煩。使用 lambda 去定義可調(diào)用對象,既簡單又方便。

sort(v.begin(), v.end(), [](const Goods& g1, const Goods& g2) {
return g1._price < g2._price;
});

因?yàn)?code>sort會將迭代器區(qū)間傳給后面的對象,所以需要兩個(gè)參數(shù)。

lambda的原理

  1. lambda 的原理和范圍for很像,編譯后從匯編指令層的角度看,壓根就沒有l(wèi)ambda 和范圍for這樣的東西。范圍for底層是迭代器,?lambda底層是仿函數(shù)對象,也就說我們寫了?個(gè)lambda 以后,編譯器會?成?個(gè)對應(yīng)的仿函數(shù)的類。
  2. 仿函數(shù)的類名是編譯按?定規(guī)則?成的,保證不同的 lambda ?成的類名不同,lambda參數(shù)/返回類型/函數(shù)體就是仿函數(shù)operator()的參數(shù)/返回類型/函數(shù)體, lambda 的捕捉列表本質(zhì)是?成的仿函數(shù)類的成員變量,也就是說捕捉列表的變量都是 lambda 類構(gòu)造函數(shù)的實(shí)參,當(dāng)然隱式捕捉,編譯器要看使?哪些就傳那些對象。

包裝器

function

std::function 是?個(gè)類模板,也是?個(gè)包裝器。 std::function 的實(shí)例對象可以包裝存儲其他的可以調(diào)?對象,包括函數(shù)指針、仿函數(shù)、 lambda 、 bind 表達(dá)式等,存儲的可調(diào)用對象被稱為 std::function 的?標(biāo)。若 std::function 不含?標(biāo),則稱它為空。調(diào)?空std::function 的?標(biāo)導(dǎo)致拋出 std::bad_function_call 異常

int f(int a, int b)
{
	return a + b;
}
struct Fun
{
public:
	int operator()(int a,int b)
	{
		return (a + b) * 10;
	}
};
int main()
{
	auto lf = [](int a, int b) {return (a + b) * 30; };
	function<int(int, int)>f1(f);
	//function<int(int, int)>f2(Fun());編譯器會將其解釋為函數(shù)聲明而不是變量定義,這被稱為"最令人煩惱的解析"
	function<int(int, int)>f2 = Fun();
	function<int(int, int)>f3(lf);
	vector<function<int(int, int)>>Vf = { f,Fun(),lf };
	cout << f1(2, 3) << endl;
	cout << f2(1, 2) << endl;
	cout << lf(4, 5) << endl;
	for (auto p : Vf)
	{
		cout << p(1, 2) << endl;
	}
	return 0;
}

函數(shù)指針、仿函數(shù)、 lambda 等可調(diào)?對象的類型各不相同, std::function 的優(yōu)勢就是統(tǒng)?類型,對他們都可以進(jìn)?包裝,這樣在很多地?就?便聲明可調(diào)?對象的類型。
可以把function當(dāng)做把可調(diào)用對象進(jìn)行統(tǒng)一為一個(gè)類型,這樣就可以將其儲存到容器中。
如果包的是成員函數(shù)的話需要注意,由于類的成員函數(shù)的第一個(gè)參數(shù)是默認(rèn)為this指針,所以function實(shí)例化的類型需要有類的對象的地址或者是對象,即使傳的是對象,對象會使用.*操作符對this指針進(jìn)行調(diào)用。

class Plus
{
	public:
	Plus(int n = 10)
	:_n(n)
	{}
	static int plusi(int a, int b)
	{
	return a + b;
	}
	double plusd(double a, double b)
	{
	return (a + b) * _n;
	}
	private:
	int _n;
};
int main()
{
	// 包裝靜態(tài)成員函數(shù)
	// 成員函數(shù)要指定類域并且前?加&才能獲取地址
	//靜態(tài)成員函數(shù)是可以不加&
	function<int(int, int)> f4 = &Plus::plusi;
	cout << f4(1, 1) << endl;
	// 包裝普通成員函數(shù)
	// 普通成員函數(shù)還有?個(gè)隱含的this指針參數(shù),所以綁定時(shí)傳對象或者對象的指針過去都可以
	function<double(Plus*, double, double)> f5 = &Plus::plusd;
	Plus pd;
	cout << f5(&pd, 1.1, 1.1) << endl;
	function<double(Plus, double, double)> f6 = &Plus::plusd;
	cout << f6(pd, 1.1, 1.1) << endl;
	cout << f6(pd, 1.1, 1.1) << endl;
	function<double(Plus&&, double, double)> f7 = &Plus::plusd;
	cout << f7(move(pd), 1.1, 1.1) << endl;
	cout << f7(Plus(), 1.1, 1.1) << endl;
}

bind

  1. bind 是?個(gè)函數(shù)模板,它也是?個(gè)可調(diào)?對象的包裝器,可以把他看做?個(gè)函數(shù)適配器,對接收的fn可調(diào)?對象進(jìn)?處理后返回?個(gè)可調(diào)?對象。 bind 可以?來調(diào)整參數(shù)個(gè)數(shù)和參數(shù)順序。bind 也在<functional>這個(gè)頭?件中。
  2. 調(diào)?bind的?般形式: auto newCallable = bind(callable,arg_list); 其中newCallable本?是?個(gè)可調(diào)?對象,arg_list是?個(gè)逗號分隔的參數(shù)列表,對應(yīng)給定的callable的參數(shù)。當(dāng)我們調(diào)?newCallable時(shí),newCallable會調(diào)用callable,并傳給它arg_list中的參數(shù)。
  3. arg_list中的參數(shù)可能包含形如_n的名字,其中n是?個(gè)整數(shù),這些參數(shù)是占位符,表?newCallable的參數(shù),它們占據(jù)了傳遞給newCallable的參數(shù)的位置。數(shù)值n表??成的可調(diào)?對象中參數(shù)的位置:_1為newCallable的第?個(gè)參數(shù),_2為第?個(gè)參數(shù),以此類推。_1/_2/_3…這些占位符放到placeholders的?個(gè)命名空間中。
using placeholders::_1;
using placeholders::_2;
using placeholders::_3;
int Sub(int a, int b)
{
	return (a - b) * 10;
}
int main()
{
	auto sub1 = bind(Sub, _1, _2);
	cout << sub1(10, 5) << endl;
	// bind 本質(zhì)返回的?個(gè)仿函數(shù)對象
	// 調(diào)整參數(shù)順序(不常?)
	// _1代表第?個(gè)實(shí)參
	// _2代表第?個(gè)實(shí)參
	// ...
	auto sub2 = bind(Sub, _2, _1);
	cout << sub2(10, 5) << endl;
	// 調(diào)整參數(shù)個(gè)數(shù) (常?)
	auto sub3 = bind(Sub, 100, _1);
	cout << sub3(5) << endl;
	auto sub4 = bind(Sub, _1, 100);
	cout << sub4(5) << endl;
	// 分別綁死第123個(gè)參數(shù)
	auto sub5 = bind(SubX, 100, _1, _2);
	cout << sub5(5, 1) << endl;
	cout << bind(SubX, 100, _1, _2)(5, 1) << endl;
	auto sub6 = bind(SubX, _1, 100, _2);
	cout << sub6(5, 1) << endl;
	auto sub7 = bind(SubX, _1, _2, 100);
	cout << sub7(5, 1) << endl;
	return 0;
}

bind對于我們之前用function來包裝成員函數(shù)時(shí)第一個(gè)參數(shù)必須傳對象的情況做出了改變,可以用bind來綁定第一個(gè)參數(shù),這樣在后續(xù)調(diào)用該可調(diào)用對象的時(shí)候就可以不用傳對象了

// 成員函數(shù)對象進(jìn)?綁死,就不需要每次都傳遞了
function<double(Plus&&, double, double)> f6 = &Plus::plusd;
Plus pd;
cout << pd.plusd(1.1, 1.1) << endl;
cout << f6(move(pd), 1.1, 1.1) << endl;
cout << f6(Plus(), 1.1, 1.1) << endl;
auto f = bind(&Plus::plusd, &pd, _1, _2);
function<double(double, double)> f2 = bind(&Plus::plusd, &pd, _1, _2);
cout << f(1.1,1.1) << endl;
cout << f2(1.1, 1.1) << endl;

到此這篇關(guān)于C++11之lambda表達(dá)式與包裝器的文章就介紹到這了,更多相關(guān)C++ lambda表達(dá)式內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • C++ 中dynamic_cast&lt;&gt;的使用方法小結(jié)

    C++ 中dynamic_cast&lt;&gt;的使用方法小結(jié)

    將一個(gè)基類對象指針(或引用)cast到繼承類指針,dynamic_cast會根據(jù)基類指針是否真正指向繼承類指針來做相應(yīng)處理
    2013-03-03
  • 深入淺析C/C++?的條件編譯

    深入淺析C/C++?的條件編譯

    條件編譯是指預(yù)處理的時(shí)候根據(jù)條件編譯的指令有條件的選擇源程序中的一部分代碼送給編譯器進(jìn)行編譯,進(jìn)行有選擇性的操作,防止宏替換的內(nèi)容重復(fù)包含,這篇文章主要介紹了C/C++?的條件編譯,需要的朋友可以參考下
    2022-04-04
  • 在C語言中使用對數(shù)函數(shù)的方法

    在C語言中使用對數(shù)函數(shù)的方法

    這篇文章主要介紹了在C語言中使用對數(shù)函數(shù)的方法,包括以e為底和以10為底的對數(shù)計(jì)算,需要的朋友可以參考下
    2015-08-08
  • C語言開發(fā)實(shí)現(xiàn)井字棋及電腦落子優(yōu)化示例詳解

    C語言開發(fā)實(shí)現(xiàn)井字棋及電腦落子優(yōu)化示例詳解

    以前上課經(jīng)常和同桌玩起井字棋,那么我們就當(dāng)我們回憶童年,現(xiàn)在也用C語言來實(shí)現(xiàn)井字棋,本次代碼相對于初階的井字棋,在電腦下棋代碼部分做了優(yōu)化,使得電腦更加具有威脅
    2021-11-11
  • 關(guān)于C++中sort()函數(shù)的用法,你搞明白了沒

    關(guān)于C++中sort()函數(shù)的用法,你搞明白了沒

    這篇文章主要介紹了關(guān)于C++中sort()函數(shù)的用法,并通過三種方法介紹了按降序排列的實(shí)現(xiàn)代碼,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-03-03
  • C語言實(shí)現(xiàn)數(shù)字雨效果

    C語言實(shí)現(xiàn)數(shù)字雨效果

    這篇文章主要為大家詳細(xì)介紹了C語言實(shí)現(xiàn)數(shù)字雨效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-02-02
  • C語言之關(guān)于二維數(shù)組在函數(shù)中的調(diào)用問題

    C語言之關(guān)于二維數(shù)組在函數(shù)中的調(diào)用問題

    這篇文章主要介紹了C語言之關(guān)于二維數(shù)組在函數(shù)中的調(diào)用問題,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-07-07
  • 帶你分分鐘玩轉(zhuǎn)C語言指針

    帶你分分鐘玩轉(zhuǎn)C語言指針

    c語言指針其實(shí)是一個(gè)整形變量,與其它數(shù)據(jù)不同的是,它的作用是用來存儲其它變量的地址,下面這篇文章主要給大家介紹了關(guān)于C語言指針的相關(guān)資料,需要的朋友可以參考下
    2022-06-06
  • C/C++ 函數(shù)原理傳參示例詳解

    C/C++ 函數(shù)原理傳參示例詳解

    這篇文章主要為大家介紹了C/C++ 函數(shù)原理傳參示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-12-12
  • C++ delete之靜態(tài)變量問題詳解

    C++ delete之靜態(tài)變量問題詳解

    這篇文章主要為大家詳細(xì)介紹了C++delete的一些問題,學(xué)習(xí)如何動(dòng)態(tài)創(chuàng)建對象,動(dòng)態(tài)創(chuàng)建的對象與一般對象的區(qū)別,動(dòng)態(tài)創(chuàng)建的對象的初始化以及釋放動(dòng)態(tài)分配的內(nèi)存等知識點(diǎn),感興趣的朋友可以參考一下
    2021-09-09

最新評論

宁都县| 白山市| 富民县| 延庆县| 玛曲县| 九台市| 罗甸县| 安吉县| 德保县| 武乡县| 砀山县| 平远县| 晋州市| 双牌县| 泰安市| 敦煌市| 崇明县| 昭觉县| 黄梅县| 新郑市| 梓潼县| 克什克腾旗| 梨树县| 铜鼓县| 玉田县| 蓬溪县| 安阳市| 读书| 新安县| 阳东县| 巴里| 石嘴山市| 青铜峡市| 阿克陶县| 古交市| 马关县| 丰都县| 小金县| 刚察县| 林州市| 垣曲县|