中文亚洲精品无码_熟女乱子伦免费_人人超碰人人爱国产_亚洲熟妇女综合网

當(dāng)前位置: 首頁 > news >正文

南坪網(wǎng)站建設(shè)安徽網(wǎng)站設(shè)計(jì)

南坪網(wǎng)站建設(shè),安徽網(wǎng)站設(shè)計(jì),公司介紹模板范文,WordPress 發(fā)布內(nèi)容目錄 1、引言 2、仿函數(shù) 3、lambda表達(dá)式 3.1、lambda表達(dá)式的一般形式 3.2、返回類型說明 3.3、捕獲列表的規(guī)則 3.4、可以捕獲哪些變量 3.5、lambda表達(dá)式給編程帶來的便利 VC常用功能開發(fā)匯總(專欄文章列表,歡迎訂閱,持續(xù)更新...&a…

目錄

1、引言

2、仿函數(shù)

3、lambda表達(dá)式

3.1、lambda表達(dá)式的一般形式

3.2、返回類型說明

3.3、捕獲列表的規(guī)則

3.4、可以捕獲哪些變量

3.5、lambda表達(dá)式給編程帶來的便利


VC++常用功能開發(fā)匯總(專欄文章列表,歡迎訂閱,持續(xù)更新...)icon-default.png?t=N7T8https://blog.csdn.net/chenlycly/article/details/124272585C++軟件異常排查從入門到精通系列教程(專欄文章列表,歡迎訂閱,持續(xù)更新...)icon-default.png?t=N7T8https://blog.csdn.net/chenlycly/article/details/125529931C++軟件分析工具從入門到精通案例集錦(專欄文章正在更新中...)icon-default.png?t=N7T8https://blog.csdn.net/chenlycly/article/details/131405795C/C++基礎(chǔ)與進(jìn)階(專欄文章,持續(xù)更新中...)icon-default.png?t=N7T8https://blog.csdn.net/chenlycly/category_11931267.html? ? ? ?C++11新特性很重要,作為C++開發(fā)人員很有必要去學(xué)習(xí),不僅筆試面試時會涉及到,開源代碼中也在大規(guī)模的使用。以很多視頻會議及直播軟件都在使用的開源WebRTC項(xiàng)目為例,WebRTC代碼中大篇幅地使用了C++11及以上的新特性,要讀懂其源碼,必須要了解這些C++的新特性。所以,接下來一段時間我將結(jié)合工作實(shí)踐,給大家詳細(xì)講解一下C++11的新特性,以供借鑒或參考。

1、引言

? ? ? ?在C++中我們可以使用函數(shù)名、函數(shù)指針、仿函數(shù)去實(shí)現(xiàn)函數(shù)的調(diào)用。C++11引入了lambda表達(dá)式,又稱匿名函數(shù),給我們引入了一種新的函數(shù)調(diào)用方式,給我們編程帶來了很大的便利。今天我們來講講仿函數(shù)和lambda表達(dá)式。

2、仿函數(shù)

? ? ? ?仿函數(shù)是一種特殊的類或結(jié)構(gòu)體,不是C++11引入的,之前就有了。它重載了函數(shù)調(diào)用運(yùn)算符operator(),并且可以像函數(shù)一樣被調(diào)用,同時它也可以擁有自己的數(shù)據(jù)成員和成員函數(shù)。仿函數(shù)通常用于算法(如sort、find、transform等)和容器(如set、map、list等)中,以提供自定義的操作行為。在C++11中,可以使用lambda表達(dá)式實(shí)現(xiàn)簡單的仿函數(shù)。

? ? ? ?下面是個類中重載 operator()的實(shí)例:

class MyFunctor
{
public:MyFunctor(int tmp) : round(tmp) {}int operator()(int tmp) { return tmp + round; }
private:int round;
};int main()
{int round = 2;MyFunctor f(round); //調(diào)用構(gòu)造函數(shù)cout << "result = " << f(1) << endl; // operator()(int tmp)return 0;
}

通過類對象去調(diào)用重載的operator()方法。 在C++里,我們通過在一個類中重載operator()運(yùn)算符的方法,去使用一個函數(shù)對象而不是一個普通函數(shù)。

? ? ? ?再看一個比較數(shù)大小的實(shí)例:

class compare_class
{public:bool operator() (int A, int B) const{return A < B;}
};// Declaration of C++ sorting function.
template<class ComparisonFunctor>
void sort_ints(int* begin_items, int num_items, ComparisonFunctor c);int main()
{int items[]={4, 3, 1, 2};compare_class functor;sort_ints( items, sizeof(items)/sizeof(items[0]), functor);
}

3、lambda表達(dá)式

? ? ? ?lambda表達(dá)式,又稱匿名函數(shù),是一個可調(diào)用的代碼單元,可以理解為一個未命名(匿名)的內(nèi)聯(lián)函數(shù)。與一般的函數(shù)類似,lambda表示式有一個返回類型、一個參數(shù)列表和一個函數(shù)體。但和函數(shù)不同的是,lambda表達(dá)式是直接定義在函數(shù)內(nèi)部。

? ? ? ?lambda表達(dá)式的引入,給我們編程帶來了很大的便利,可以大大簡化我們的編碼!

3.1、lambda表達(dá)式的一般形式

lambda表達(dá)式的一般形式如下:

[capture list]( parameter list ) -> return type { function body }

其中:

1)capture list(捕獲列表),是一個本表達(dá)式所在函數(shù)的局部變量的列表;
2)parameter list(參數(shù)列表),是給本lambda表達(dá)式傳入的參數(shù)列表;
3)return type(返回類型),是本lambda表達(dá)式的返回值類型(可省略);
4)function body(函數(shù)體),是本lambda表達(dá)式的內(nèi)部實(shí)現(xiàn)。

? ? ? ?對于普通函數(shù),返回類型位于函數(shù)開始處,但lambda表達(dá)式因?yàn)槠湫问?#xff0c;返回類型不能放在開始處,必須使用尾置的方式來指定返回類型。我們可以忽略參數(shù)列表和返回值類型,但必須包含捕獲列表和函數(shù)體,比如:

auto f = [] { return 20; };

3.2、返回類型說明

? ? ? ?直接在lambda表達(dá)式中指定返回類型,沒什么問題。下面我們看看沒指定返回類型時,將會發(fā)生什么。

? ? ? ?如果lambda表達(dá)式的函數(shù)體中只包含一個return語句,如果沒指定lambda表達(dá)式的返回值,則編譯時會根據(jù)return語句中的內(nèi)容推導(dǎo)出本表達(dá)式的返回值類型,比如實(shí)現(xiàn)兩個整型數(shù)據(jù)相加的lambda表達(dá)式:

[] ( int a, int b) { return a + b; }

本lambda中沒有指定函數(shù)返回類型,根據(jù)表達(dá)式(a+b)可以推斷出本lambda返回值類型為int。

? ? ? ?如果lambda表示式中不是只包含單一的return語句(多條語句),編譯時編譯器認(rèn)定該lambda返回值類型為void。比如返回一個數(shù)絕對值的lambda如下:

[] ( int a ) { if ( a < 0) return -a; else return a; };

因?yàn)榘硕鄺l語句,所以編譯器認(rèn)定該lambda返回void,編譯時會報(bào)錯!因?yàn)榉祷仡愋蜑関oid,卻使用return返回了int類型,不一致了,所以報(bào)錯!

3.3、捕獲列表的規(guī)則

? ? ? ?捕獲列表,涉及到訪問所在函數(shù)哪些局部變量,以及訪問變量的方式。訪問變量的方式主要有以引用的方式訪問,還是以值的方式訪問。如果是將lambda要訪問的變量在捕獲列表中羅列出來,則是顯示捕獲;如果不羅列,就是隱式捕獲。

? ? ? ?下面給出完整的捕獲列表規(guī)則:

捕獲類型描述
[]空捕獲列表。lamda表達(dá)式內(nèi)部不使用所在函數(shù)中的變量。只有捕獲列表不為空才能使用所在函數(shù)中的變量。
[names]names是一個逗號分割的名字列表,這些名字是lamda所在函數(shù)的局部變量的名稱。默認(rèn)情況下,捕獲列表中的變量值被拷貝,變量前面可以添加&,加&則表示采用引用捕獲方式。
[&]隱式捕獲列表,讓編譯器根據(jù)lamda內(nèi)部的代碼去推斷使用了所在函數(shù)的哪些局部變量。采用引用捕獲方式,lamda體中所使用的來自所在函數(shù)的變量都采用引用方式使用。
[=]隱式捕獲列表,讓編譯器根據(jù)lamda內(nèi)部的代碼去推斷使用了所在函數(shù)的哪些局部變量。采用值捕獲方式,lamda體中將拷貝所使用的來自所在函數(shù)的變量的值。
[&, identifier_list]?identifier_list(理解為不使用&引用捕獲的特例)是逗號分割的列表,包含0個或多個來自所在函數(shù)的變量,這些變量采用值捕獲,identifier_list列表中的名字前面不能加&。而除identifier_list列表中指明的變量之外的任何隱式捕獲的變量都采用引用捕獲方式。
[=, identifier_list]identifier_listt(理解為不使用=值捕獲的特例)是逗號分割的列表,包含0個或多個來自所在函數(shù)的變量,這些變量采用引用捕獲,identifier_list列表中的名字前面必須使用&。而除identifier_list列表中指明的變量之外任何隱式捕獲的變量都采用值捕獲方式。

關(guān)于捕獲列表的例子,如下:

int main()
{int a = 0, b = 1;auto f1 = []{ return a; }; ? ? ?// error, 沒有捕獲外部變量auto f2 = [=]{ return a; }; ? ? // ok, 值傳遞方式捕獲所有外部變量auto f3 = [=]{ return a++; }; ? // error, a是以賦值方式捕獲的,無法修改auto f4 = [=]() mutable { return a++; }; ? // ok, 加上mutable修飾符后,可以修改按值傳遞進(jìn)來的拷貝auto f5 = [&]{ return a++; }; ? ? ? ? ? ? ?// ok, 引用傳遞方式捕獲所有外部變量, 并對a執(zhí)行自加運(yùn)算auto f6 = [a]{ return a+b; }; ? ? ? ? ? ? ?// error, 沒有捕獲變量bauto f9 = [a,&b]{ return a+(b++); }; ? ? ? // ok, 捕獲a, &bauto f8 = [=,&b]{ return a+(b++); }; ? ? ? // ok, 捕獲所有外部變量,&bauto f9 = [&,&b]{ return a+(b++); }; ? ? ? // error, 捕獲所有外部變量,不能使用&b,b是特例,和默認(rèn)的引用捕獲不一樣,使用值捕獲,所以不能加&auto f10 = [=,b]{ return a+(b++); }; ? ? ? // error, 捕獲所有外部變量,不能使用b,b是特例,和默認(rèn)的值引用不一樣,使用引用捕獲,前面必須加&return 0;
}

3.4、可以捕獲哪些變量

? ? ? ?一般lambda表達(dá)式是放置在一個函數(shù)中的,即在函數(shù)中嵌入的,lambda函數(shù)實(shí)現(xiàn)體中可以訪問其所在函數(shù)的局部變量。如果lambda表達(dá)式所在函數(shù)是一個類的成員函數(shù),則lambda內(nèi)部也可以訪問當(dāng)前函數(shù)所在的類的成員變量,這一點(diǎn)可能很多人不知道。比如:

class Test
{
public:int i = 0; ? // 類的成員變量void func(int x, int y){auto x1 = []{ return i; }; ? ? ? ? ?// error, 沒有捕獲外部變量auto x2 = [=]{ return i+x+y; }; ? ? // ok, 值傳遞方式捕獲所有外部變量auto x3 = [=]{ return i+x+y; }; ? ? // ok, 引用傳遞方式捕獲所有外部變量auto x4 = [this]{ return i; }; ? ? ?// ok, 捕獲this指針auto x5 = [this]{ return i+x+y; }; ?// error, 沒有捕獲x, yauto x6 = [this, x, y]{ return i+x+y; };// ok, 捕獲this指針, x, yauto x9 = [this]{ return i++; }; ? ? ? ?// ok, 捕獲this指針, 并修改成員的值}
};

3.5、lambda表達(dá)式給編程帶來的便利

? ? ? ?lambda表達(dá)式的引入,給我們編程帶來了很大的便利,可以大大簡化我的編碼。比如我們在使用STL容器的find_if、count_if、sort等算法函數(shù)時,我們要傳入條件函數(shù)或者比較函數(shù),這些函數(shù)直接用lambda表達(dá)式去實(shí)現(xiàn),要方便很多。
? ? ? ?在以前沒有l(wèi)ambda表達(dá)式時,這些條件函數(shù)和比較函數(shù),需要在函數(shù)外實(shí)現(xiàn),要不定義成全局函數(shù),要不定義成靜態(tài)函數(shù),甚至還要定義一些輔助的全部或者靜態(tài)變量。比如有一個存放設(shè)備信息的結(jié)構(gòu)體,然后有個存放設(shè)備信息的vector列表,給該列表簡單的初始化一下:

// 設(shè)備信息結(jié)構(gòu)體
typedef struct tagDeviceInfo
{char szDeviceId[64]; ? // 設(shè)備idchar szDeviceName[64]; // 設(shè)備名稱int nDevType; ? ? ? ? ?// 設(shè)備類型public:tagDeviceInfo(){ memset(this, 0, sizeof(tagDeviceInfo)); }
}TDeviceInfo;// 設(shè)備管理類
class CDeviceManage
{CDeviceManage();~CDeviceManage();void InitDeviceList();private:vector<TDeviceInfo> m_vtDevList;
}// 初始化設(shè)備列表(僅用于測試,隨意初始化了一些數(shù)據(jù))
void CDeviceManage::InitDeviceList()
{for ( int i = 0; i < 10; i++ ){TDeviceInfo tDevInfo;char szBuf[128] = { 0 };sprintf(szBuf, "E40CF3E4-CC2B-437F-A4B9-65F2D5BD071%d", i);strcpy(tDevInfo.szDeviceId, szBuf);CUIString strName;sprintf(szBuf, "設(shè)備%d", i);strcpy(tDevInfo.szDeviceName, szBuf);m_vtDevList;.push_back(tDevInfo);}
}

假設(shè)我們在CDeviceManage::FindTest成員函數(shù)中調(diào)用STL的算法函數(shù)find_if到m_vtDevList列表中搜索設(shè)備Guid(szDeviceId)為E40CF3E4-CC2B-437F-A4B9-65F2D5BD0715的設(shè)備信息。如果不使用lambda表達(dá)式,則要將條件函數(shù)實(shí)現(xiàn)在CDeviceManage類外部定義成全局函數(shù),同時要將存放目標(biāo)id的變量定義成全局的,如下所示:

char* s_lpszTargetDevId = ""; // 定義成靜態(tài)變量// 將條件匹配函數(shù)定義在類CDeviceManage外部,定義成全局函數(shù)
BOOL MatchFunc(TDeviceInfo& tDevInfo)
{return strcmp( s_lpszTargetDevId,tDevInfo.szDeviceId ) == 0;
}bool CDeviceManage::FindTest()
{// 對靜態(tài)變量s_pTargetDevId進(jìn)行賦值s_lpszTargetDevId = "E40CF3E4-CC2B-437F-A4B9-65F2D5BD0715";vector<TDeviceInfo>::iterator itor = std::find_if(m_vtDevList.begin(), m_vtDevList.end(), MatchFunc);if ( itor != m_vtDevList.end() ){// 找到對應(yīng)的設(shè)備信息,進(jìn)行后續(xù)處理的代碼省略// ......return true;}return false;
}

上述代碼實(shí)現(xiàn)的相對麻煩一些。
? ? ? ?如果使用lambda表達(dá)式,代碼要簡潔很多,不用將條件匹配函數(shù)定義成全局函數(shù),也不用定義靜態(tài)輔助變量s_lpszTargetDevId,用lambda表達(dá)式實(shí)現(xiàn)的代碼如下:

bool CDeviceManage::FindTest()
{char* lpszTargetDevId = "E40CF3E4-CC2B-437F-A4B9-65F2D5BD0715";vector<TDeviceInfo>::iterator itor = std::find_if(vtDevList.begin(), vtDevList.end(), [=](const TDeviceInfo& tDevInfo){return strcmp(lpszTargetDevId, tDevInfo.achDeviceId) == 0; } );// 后續(xù)代碼省略// ......
}

? ? ? ? 至于為什么要使用STL的算法函數(shù)去搜索, 因?yàn)镾TL的算法函數(shù)的效率比較高,比直接去for循環(huán)遍歷效率會高很多!如果STL列表中存放了大量的數(shù)據(jù),數(shù)據(jù)搜索就要講究效率了,就要使用到STL算法函數(shù),比直接for循環(huán)變量要高上幾個數(shù)量級,這點(diǎn)在項(xiàng)目中對比測試過!關(guān)于使用STL算法函數(shù)提高搜索效率的文章,可以參見我之前寫的文章:

VC++調(diào)用STL算法函數(shù)有效提升STL列表的搜索速度(附源碼)icon-default.png?t=N7T8https://blog.csdn.net/chenlycly/article/details/123943134VC++如何使用C++ STL標(biāo)準(zhǔn)模板庫中的算法函數(shù)(附源碼)icon-default.png?t=N7T8https://blog.csdn.net/chenlycly/article/details/125486409

http://www.risenshineclean.com/news/5286.html

相關(guān)文章:

  • 在線app開發(fā)平臺黑帽seo是作弊手法
  • 政府網(wǎng)站信息建設(shè)工作軟文代寫兼職
  • app應(yīng)用下載網(wǎng)站源碼做網(wǎng)絡(luò)推廣費(fèi)用
  • 江西網(wǎng)站備案流程全網(wǎng)推廣怎么做
  • 濟(jì)南建站哪家好外貿(mào)獨(dú)立站怎么建站
  • 浙江網(wǎng)站備案查詢百度推廣怎么才能效果好
  • 白云網(wǎng)站制作視頻運(yùn)營管理平臺
  • 表白網(wǎng)站制作系統(tǒng)源碼怎么關(guān)閉seo綜合查詢
  • 深圳建站網(wǎng)站模板網(wǎng)絡(luò)營銷有哪些手段
  • wordpress獲取權(quán)限星沙網(wǎng)站優(yōu)化seo
  • 在網(wǎng)站上可以做哪些互動活動微信軟文廣告經(jīng)典案例
  • 一個做問卷調(diào)查的網(wǎng)站好持續(xù)優(yōu)化疫情防控舉措
  • 成都web網(wǎng)站開發(fā)重慶網(wǎng)站制作公司哪家好
  • 網(wǎng)站策劃編輯如何做網(wǎng)站建站流程
  • 銀川微信網(wǎng)站制作網(wǎng)絡(luò)推廣app是違法的嗎
  • 湖南響應(yīng)式網(wǎng)站哪里有seo網(wǎng)絡(luò)優(yōu)化平臺
  • 中國建設(shè)銀行上海分行信息網(wǎng)站廣東東莞大益隊(duì)
  • 網(wǎng)站建設(shè)哪里好產(chǎn)品推廣找哪家公司
  • 關(guān)于加強(qiáng)網(wǎng)站建設(shè)的意見網(wǎng)站后臺管理系統(tǒng)
  • github 搭建網(wǎng)站怎樣打小廣告最有效
  • 邳州徐州網(wǎng)站開發(fā)軟文標(biāo)題
  • 網(wǎng)站建設(shè)資金的請示個人網(wǎng)頁制作教程
  • 網(wǎng)站備案 哪個省最松發(fā)外鏈的平臺有哪些
  • 新東陽建設(shè)集團(tuán)網(wǎng)站電商詳情頁模板免費(fèi)下載
  • 做教育的有哪些網(wǎng)站seo推廣優(yōu)化排名軟件
  • 上海網(wǎng)站建設(shè)免企業(yè)seo排名
  • 郵箱163企業(yè)郵箱女生seo專員很難嗎為什么
  • 寵物網(wǎng)站制作費(fèi)用明細(xì)今日廣州新聞最新消息
  • 網(wǎng)站開發(fā)需要什么東西百度seo排名優(yōu)化費(fèi)用
  • wordpress 地理定位網(wǎng)絡(luò)優(yōu)化的內(nèi)容包括哪些