成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

C++的匿名函數(shù)(lambda表達(dá)式)

開發(fā) 后端
C++11提供了對匿名函數(shù)的支持,稱為Lambda函數(shù)(也叫Lambda表達(dá)式). 它是定義和使用匿名函數(shù)對象的一種簡便的方式。

[[346604]]

 總述

C++11提供了對匿名函數(shù)的支持,稱為Lambda函數(shù)(也叫Lambda表達(dá)式). 它是定義和使用匿名函數(shù)對象的一種簡便的方式。匿名函數(shù)是我們需要用到的一個(gè)函數(shù),但是又不想去費(fèi)力命名一個(gè)函數(shù)的場景。我們無需為每個(gè)值或者每種類型)單獨(dú)編寫函數(shù),更不必把值保存在讓人厭倦的全局變量中 。 利用lambda表達(dá)式可以編寫內(nèi)嵌的匿名函數(shù),用以替換獨(dú)立函數(shù)或者函數(shù)對象,并且使代碼更可讀。

工作的時(shí)候這個(gè)是比較常用的,通過匿名函數(shù)進(jìn)行函數(shù)內(nèi)部變量的捕獲,繼而進(jìn)行操作變量等。那么現(xiàn)在就由我來給大家分享一下,我對Lambda表達(dá)式的認(rèn)知,僅作為一個(gè)基礎(chǔ)的介紹哈,畢竟C++博大精深,吾輩還需要深究。

1.它的結(jié)構(gòu)

一條lambda表達(dá)式一般會有以下部分:

1.一個(gè)可能為空的捕獲列表,指明定義環(huán)境中的那些名字能被用在lambda表達(dá)式內(nèi),以及這些名字的訪問形式拷貝還是引用,捕獲列表位于 [] 內(nèi)。

2.一個(gè)可選的參數(shù)列表,指明lambda表達(dá)式所需的參數(shù),參數(shù)列表位于 () 內(nèi)。

3.一個(gè)可以選的mutable修飾符,指明該lambda表達(dá)式可能會修改它自身的狀態(tài)(即,改變通過值捕獲的變量的副本)

4.一個(gè)可選的 -> 形式的返回類型聲明

5.一個(gè)表達(dá)式體,指明要執(zhí)行的代碼,表達(dá)式位于 {} 內(nèi)。

  1. [捕獲列表](參數(shù)列表) mutable(可選) 異常屬性 -> 返回類型 { 
  2. // 函數(shù)體 

上面的語法規(guī)則除了 [捕獲列表] 內(nèi)的東西外,其他部分都很好理解,只是一般函數(shù)的函數(shù)名被略去, 返回值使用了一個(gè) -> 的形式進(jìn)行。

所謂捕獲列表,其實(shí)可以理解為參數(shù)的一種類型,lambda 表達(dá)式內(nèi)部函數(shù)體在默認(rèn)情況下是不能夠使用函數(shù)體外部的變量的, 這時(shí)候捕獲列表可以起到傳遞外部數(shù)據(jù)的作用。

在lambda中,傳參、返回結(jié)果以及定義表達(dá)式體和普通的函數(shù)都是一致的,區(qū)別就在于普通函數(shù)沒有提供局部變量“捕獲”功能,而局部捕獲的功能,就意味著lambda可以做局部函數(shù)使用,而普通函數(shù)不能。

展示一個(gè)小例子證明lambda表達(dá)式的簡潔性:

Greater than 是一個(gè)函數(shù)對象,保存了要比較的值:

  1. struct Greater_than ( 
  2.   int val; 
  3.   Greater_than(lnt v) : val{v} { } 
  4.   bool operatorO(const pair<string.int>& r) { return r.second>val; 
  5. }; 

我們也可以使用 lambda 表達(dá)式 :

  1. auto p =find_if(m.beginO, m.endO, 
  2.  [](const pair<string, int>& r) { return r.second>42; });  

每當(dāng)你定義一個(gè)lambda表達(dá)式后,編譯器會自動生成一個(gè)匿名類(這個(gè)類當(dāng)然重載了()運(yùn)算符),我們稱為閉包類型(closure type)。

2.基本的參數(shù)分析

C++11中的Lambda表達(dá)式捕獲外部變量主要有以下形式:

  • []:默認(rèn)不捕獲任何變量;
  • [=]:默認(rèn)以值捕獲所有變量;
  • [&]:默認(rèn)以引用捕獲所有變量;
  • [x]:僅以值捕獲x,其它變量不捕獲;
  • [&x]:僅以引用捕獲x,其它變量不捕獲;
  • [=, &x]:默認(rèn)以值捕獲所有變量,但是x是例外,通過引用捕獲;
  • [&, x]:默認(rèn)以引用捕獲所有變量,但是x是例外,通過值捕獲;
  • [this]:通過引用捕獲當(dāng)前對象(其實(shí)是復(fù)制指針);
  • [*this]:通過傳值方式捕獲當(dāng)前對象;

在上面的捕獲方式中,注意最好不要使用[=]和[&]默認(rèn)捕獲所有變量。首先說默認(rèn)引用捕獲所有變量,你有很大可能會出現(xiàn)懸掛引用(Dangling references),因?yàn)橐貌东@不會延長引用的變量的聲明周期,例如一個(gè)形參傳進(jìn)來我們進(jìn)行捕獲并作為一個(gè)返回值執(zhí)行。因?yàn)楹瘮?shù)傳參進(jìn)來之后,本函數(shù)不會保存該變量,函數(shù)執(zhí)行完就會自動釋放,那么這個(gè)時(shí)候返回值就可能產(chǎn)生一個(gè)沒有意義的結(jié)果。

  1. auto evt_set_status_x = [&](EventType x) 
  2.   status[x] = true;/*通過引用捕獲的變量 我們可以進(jìn)行修改變量的數(shù)據(jù)*/ 
  3. }; 

[&]是一個(gè)捕獲列表( capture l ist ), 它指明所用的局部名字(如 x) 將通過引用訪問 。如果我們希望只"捕獲 "x ,則可以寫成 [&x] ;如果希望給生成的函數(shù)對象傳遞一個(gè) 的拷貝, 則寫成[ x] 。什么也不捕獲是[],捕獲所有通過引用訪問的局部名字是[&],捕獲所有以值訪問的局部名字是[=] 。

并且lambda表達(dá)式也可以賦值給相對應(yīng)的函數(shù)指針,這也使得你完全可以把lambda表達(dá)式看成對應(yīng)函數(shù)類型的指針。

當(dāng)我們需要訪問它的局部變量的時(shí)候,我們需要特別定義捕獲列表中的類型

下面是一個(gè)沒有使用局部變量的lambda表達(dá)式,所以它的[]里面為空

  1. void part(vector<int>& v) 
  2.     sort(v.begin,v.end);//排列值 
  3.  
  4.     sort(v.begin,v.end
  5.             [](int x,int y){return abs(x) < abs(y);});//排列絕對值 
  6.  

下面是一個(gè)使用局部變量的lambda表達(dá)式,所以它的[]里面為空就會出錯(cuò)

  1. void part(vector<int>& v) 
  2.     bool value = true
  3.  
  4.     sort(v.begin,v.end
  5.             [](int x,int y){return  value ? x<y:abs(x) < abs(y);});/ 
  6.  

這時(shí)候就錯(cuò)誤了,因?yàn)槲覀冇玫搅藇alue這個(gè)局部變量,而沒有進(jìn)行捕獲列表的設(shè)置。

3.捕獲使用分析

使用 lambda 雖然簡單便捷,但也有可能顯得晦澀難懂 。

值捕獲

與參數(shù)傳值類似,值捕獲的前提是變量可以拷貝,不同之處則在于,被捕獲的變量在 lambda 表達(dá)式被創(chuàng)建時(shí)拷貝, 而非調(diào)用時(shí)才拷貝:

  1. #include <iostream> 
  2. void value_capture() { 
  3.     int value = 1; 
  4.     auto copy_value = [value] { 
  5.         return value; 
  6.     }; 
  7.     value = 100; 
  8.     auto stored_value = copy_value(); 
  9.     std::cout << "stored_value = " << stored_value << std::endl; 
  10.  
  11. int main(int argc,char ** argv) 
  12.   value_capture(); 
  13. // 這時(shí), stored_value == 1, 而 value == 100. 
  14. // 因?yàn)?nbsp;copy_value 在創(chuàng)建時(shí)就保存了一份 value 的拷貝 

記得編譯的時(shí)候加 -std=c++11

引用捕獲

與引用傳參類似,引用捕獲保存的是引用,值會發(fā)生變化:

  1. void reference_capture() { 
  2.     int value = 1; 
  3.     auto copy_value = [&value] { 
  4.         return value; 
  5.     }; 
  6.     value = 100; 
  7.     auto stored_value = copy_value(); 
  8.     std::cout << "stored_value = " << stored_value << std::endl; 
  9.     // 這時(shí), stored_value == 100, value == 100. 
  10.     // 因?yàn)?nbsp;copy_value 保存的是引用 

泛型lambda表達(dá)式

從C++14開始,lambda表達(dá)式支持泛型:其參數(shù)可以使用自動推斷類型的功能,而不需要顯示地聲明具體類型。這就如同函數(shù)模板一樣,參數(shù)要使用類型自動推斷功能,只需要將其類型指定為auto,類型推斷規(guī)則與函數(shù)模板一樣。就用我最早給出的那個(gè)例子好了。

  1. auto evt_set_status_x = [&](EventType x) 
  2.   status[x] = true
  3. }; 

本文轉(zhuǎn)載自微信公眾號「羽林君」,可以通過以下二維碼關(guān)注。轉(zhuǎn)載本文請聯(lián)系羽林君公眾號。

 

責(zé)任編輯:武曉燕 來源: 羽林君
相關(guān)推薦

2023-11-02 08:25:58

C++Lambda

2022-09-19 14:12:27

C++Lambda表達(dá)式

2021-08-31 07:19:41

Lambda表達(dá)式C#

2023-03-23 18:40:18

Lambda編程C++

2023-09-25 13:28:14

C++Lambda

2009-08-27 09:44:59

C# Lambda表達(dá)

2024-03-25 13:46:12

C#Lambda編程

2009-07-09 09:51:07

Lambda表達(dá)式C#

2009-08-31 17:11:37

Lambda表達(dá)式

2009-08-27 09:57:50

C# Lambda表達(dá)

2009-08-26 16:17:23

C# Lambda表達(dá)

2009-09-14 13:57:20

C# Lambda表達(dá)Lambda表達(dá)式

2012-06-26 10:03:58

JavaJava 8lambda

2009-07-01 09:56:10

C#3.0

2009-09-09 13:01:33

LINQ Lambda

2009-09-15 15:18:00

Linq Lambda

2022-12-05 09:31:51

接口lambda表達(dá)式

2009-09-11 09:48:27

Linq Lambda

2009-08-10 10:06:10

.NET Lambda

2022-11-07 07:11:19

C#lambda函數(shù)
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號

主站蜘蛛池模板: 欧美日韩成人在线 | 日韩欧美在线一区 | 成人国产精品久久久 | 欧美在线视频二区 | 国产欧美一区二区三区久久手机版 | 亚洲欧美另类在线观看 | 日韩一区二区在线免费观看 | 成人激情视频免费观看 | 日韩在线看片 | 激情网站在线观看 | 91热在线| 亚洲成人av一区二区 | 国产精品嫩草影院精东 | 在线中文字幕日韩 | 日韩免费毛片视频 | 欧美一级做a爰片免费视频 国产美女特级嫩嫩嫩bbb片 | 国产1区2区3区 | 国产在线播 | 国产亚洲精品成人av久久ww | 蜜桃五月天 | 久久久精选 | 成人午夜网 | 久久久www成人免费精品 | 成年人在线观看 | 免费在线看a | 特级黄一级播放 | 久久综合香蕉 | 国产在线视频在线观看 | 亚洲一区二区网站 | 国产小u女发育末成年 | 日韩中文字幕一区二区 | 精品免费| 成人性生交大片 | 欧美久久一区二区三区 | 伊人网在线播放 | 青青久久久| 久久久婷| 日韩精品在线看 | 国产日本精品视频 | 伊人手机在线视频 | 欧美一级片在线看 |