【C++】簡單介紹lambda表達式

在這里插入圖片描述
各位大佬好,我是落羽!一個堅持不斷學習進步的學生。
如果您覺得我的文章還不錯,歡迎多多互三分享交流,一起學習進步!

也歡迎關注我的blog主頁: 落羽的落羽

文章目錄

  • 一、 什么是lambda表達式
  • 二、 表達式語法
  • 三、lambda的應用

一、 什么是lambda表達式

C++中有“可調用對象”的概念,主要包括函數指針、仿函數、lambda表達式。lambda表達式本質是一個匿名函數對象,跟普通函數不同的是,他可以定義在函數內部

lambda表達式在語法使用層面上“沒有類型”,簡單來說:lambda表達式的類型是編譯器即時生成的、唯一的、匿名的,程序員無法在代碼中直接寫出它的類型名稱。lambda表達式使用時本質是被轉換成一個仿函數再使用的,每個lambda表達式都會被編譯器轉換成一個獨一無二的、匿名的類(仿函數)。即使兩個lambda看起來完全一樣,編譯器也會為它們生成兩個不同的類。所以,我們一般都是用auto或者模板參數定義的對象去接收lambda對象

二、 表達式語法

lambda表達式的語法格式是:[capture-list](parameters)->return-type {function body}

  • (parameters):參數列表。與普通的函數參數列表功能類似,如果不需要傳參,則可以連同()一起省略。
  • ->return-type:return type是lambda函數的返回值類型。如果沒有返回值,那么->return type這部分就可以省略,或者返回值類型明確的情況下,能由編譯器自動推導返回類型出來,也能省略這部分。
  • {function body}:函數體。函數體的實現與普通函數完全一樣,函數體內除了能使用參數列表外,還可以使用捕捉列表內的變量。函數體為空也必須寫{}
  • [capture-list]:捕捉列表。該列表寫在lambda表達式的開始位置,編譯器根據[]來判斷接下來的代碼是否為lambda函數。捕捉列表能夠捕捉上下文的變量,以供lambda函數內部使用,捕捉列表可以傳值或傳引用,捕捉列表就算為空也必須寫[]

舉幾個栗子:

auto add = [](int x, int y){ return x + y; };

在這里插入圖片描述

auto func = []{cout << "hello world" << endl;};

在這里插入圖片描述

auto swap = [](int& a, int& b){int tmp = a;a = b;b = tmp;};

在這里插入圖片描述
非常好理解吧!

關于捕捉列表,還有一些使用的細節:

lambda表達式中默認只能使用參數列表中的變量或lambda內定義的,如果想使用外層作用域中的變量就需要進行捕捉。

  • 第一種方式是顯式捕捉,在捕捉列表中可以顯式傳值捕捉和傳引用捕捉,捕捉的多個變量用逗號分隔,比如[x, y, &z]表示x和y進行傳值捕捉,lambda內部改變x和y不會改變原變量,而z是傳引用捕捉,對z的改變會改變原變量。
  • 第二種捕捉方式是隱式捕捉,我們在[ ]中寫一個 = 表示隱式值捕捉,寫一個 & 表示隱式引用捕捉。這樣我們的lambda的表達式中使用了哪些外部變量,編譯器就會自動捕捉那些變量。
  • 第三種捕捉列表是混合捕獲,可以組合使用隱式捕獲和顯式捕獲,實現更精細的控制。[=, &x] 表示x進行引用捕捉,其余變量都為值捕捉;[&, x, y] 表示x和y進行值捕捉,其余變量進行引用捕捉。使用混合捕捉時,第一個元素必須是=或&,第一個是=時,后面的捕捉變量必須是引用捕捉;第一個是&時,后面的捕捉變量必須是值捕捉。

lambda表達式中如果在局部域時,可以捕捉到它之前定義的變量,不能捕捉靜態局部變量和全局變量,因為這兩種變量本來就不需要捕捉也能在內部直接使用,lambda表達式內部可以直接使用。lambda表達式如果定義在全局位置,捕捉列表必須為空。

默認情況下,lambda捕捉列表是const屬性的,也就是說傳值捕捉來的對象不能被修改,在參數列表后加上修飾符mutable就可以取消其常性,但是修改還是改變的形參對象,不會影響實參。使用該修飾符后參數列表不能省略。

int x = 0;
// 捕捉列表必須為空,因為全局變量不?捕捉就可以?,沒有可被捕捉的變量
auto func1 = [](){x++;};int main()
{// 只能?當前lambda局部域和捕捉的對象和全局對象int a = 0, b = 1, c = 2, d = 3;auto func1 = [a, &b]{// 值捕捉的變量不能修改,引?捕捉的變量可以修改//a++;b++;int ret = a + b;return ret;};cout << func1() << endl;// 隱式值捕捉// ?了哪些變量就捕捉哪些變量auto func2 = [=]{int ret = a + b + c;return ret;};cout << func2() << endl;// 隱式引?捕捉// ?了哪些變量就捕捉哪些變量auto func3 = [&]{a++;c++;d++;};func3();cout << a << " " << b << " " << c << " " << d << endl;// 混合捕捉1auto func4 = [&, a, b]{//a++;//b++;c++;d++;return a + b + c + d;};func4();cout << a << " " << b << " " << c << " " << d << endl;// 混合捕捉1auto func5 = [=, &a, &b]{a++;b++;/*c++;d++;*/return a + b + c + d;};func5();cout << a << " " << b << " " << c << " " << d << endl;// 局部的靜態和全局變量不能捕捉,也不需要捕捉static int m = 0;auto func6 = []{int ret = x + m;return ret;};// 傳值捕捉本質是?種拷?,并且被const修飾了// mutable相當于去掉const屬性,可以修改了// 但是修改了不會影響外?被捕捉的值,因為是?種拷?auto func7 = [=]()mutable{a++;b++;c++;d++;return a + b + c + d;};cout << func7() << endl;cout << a << " " << b << " " << c << " " << d << endl;return 0;
}

三、lambda的應用

學習lambda表達式之前,我們使用的可調用對象只有函數指針和仿函數,它們的定義都相對麻煩,使用lambda表達式去定義可調用對象,就十分簡單方便了。

vector<pair<int, int>> v = { {1,2}, {3,4}, {8,3}, {5,1} };
//遇到這樣的場景,假如我們想要用多種排序規則進行排序,以前是需要寫不同的仿函數傳給sort/*struct Compare_first
{bool operator()(const pair<int, int>& p1, const pair<int, int>& p2){return p1.first < p2.first;}
}; 
struct Compare_second
{bool operator()(const pair<int, int>& p1, const pair<int, int>& p2){return p1.second < p2.second;}
};
sort(v.begin(), v.end(), Compare_first());
sort(v.begin(), v.end(), Compare_second());*///有了lambda表達式后,就方便許多了
sort(v.begin(), v.end(), [](const pair<int, int>& p1, const pair<int, int>& p2) {return p1.first < p2.first; });
for (auto pa : v)
{cout << pa.first << ":" << pa.second << " ";
}
cout << endl;sort(v.begin(), v.end(), [](const pair<int, int>& p1, const pair<int, int>& p2) {return p1.second < p2.second; });
for (auto pa : v)
{cout << pa.first << ":" << pa.second << " ";
}
cout << endl;

在這里插入圖片描述

本篇完,感謝閱讀。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/96016.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/96016.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/96016.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

磁共振成像原理(理論)4:自由進動和弛豫 (Free Precession and Relaxation)

當磁化自旋系統被射頻脈沖擾動而偏離其熱平衡態后&#xff0c;一旦移除外部激勵并給予足夠時間&#xff0c;系統將根據熱力學定律返回平衡態。這一過程包含三個特征現象&#xff1a; (a) 自由進動——宏觀磁化矢量 (M?\vec{M}M) 繞( B0?\vec {B_0}B0?? )場的進動&#xff1…

ubuntu 20.04 安裝spark

安裝openjdk21 下載 wget https://download.java.net/openjdk/jdk21/ri/openjdk-2135_linux-x64_bin.tar.gz解壓 tar -xvf openjdk-2135_linux-x64_bin.tar.gzsudo mv jdk-21/ /opt/jdk-21/設置環境變量 echo export JAVA_HOME/opt/jdk-21 | sudo tee /etc/profile.d/java2…

第三方區塊鏈應用測評:【多簽錢包合約安全評估_閾值簽名機制與私鑰存儲安全性測試】

閾值簽名機制安全測試密碼學審計 采用門限簽名方案&#xff08;TSS&#xff09;的多簽錢包需驗證其閾值BLS簽名或ECDSA簽名算法的正確性。測試重點包括&#xff1a;分布式密鑰生成&#xff08;DKG&#xff09;過程的保密性&#xff08;無密鑰信息泄露&#xff09;、簽名碎片驗證…

大模型處理長文檔的挑戰和解決方案?

當前&#xff0c;AI 應用正處于極速發展階段&#xff0c;大語言模型&#xff08;LLM&#xff09;與檢索增強生成&#xff08;RAG&#xff09;系統已成為構建智能問答、知識管理等高階 AI 應用的核心引擎&#xff0c;被廣泛應用于金融分析、學術研究、企業合規等多個領域。然而&…

JavaWeb--day1--HTMLCSS

(以下內容全部來自上述課程及課件) web開發介紹 1. 什么是web&#xff1f; Web&#xff1a;全球廣域網&#xff0c;也稱為萬維網&#xff0c;能夠通過瀏覽器訪問的網站。 2. Web網站的工作流程 3. Web標準 Web標準也稱為網頁標準&#xff0c;由一系列的標準組成&#xf…

OpenEuler安裝gitlab,部署gitlab-runner

目錄 一、安裝gitlab 二、安裝部署docker設置源 三、下載部署runner ?編輯 四、構建CI/CD 一、安裝gitlab 1.查看OpenEuler版本 [rootlocalhost ~]# cat /etc/os-release NAME"openEuler" VERSION"24.03 (LTS-SP1)" ID"openEuler" VERSI…

實戰項目-----在圖片 hua.png 中,用紅色畫出花的外部輪廓,用綠色畫出其簡化輪廓(ε=周長×0.005),并在同一窗口顯示

實戰項目實現以下功能&#xff1a;對圖片 hua.png 進行輪廓提取&#xff0c;并在同一窗口中完成以下兩個繪制操作&#xff1a;用紅色畫出花的外部輪廓&#xff08;即最外層輪廓&#xff09;用綠色畫出該輪廓的近似多邊形&#xff0c;其中近似精度參數 ε 設置為輪廓周長的 0.00…

開源鴻蒙北向框架開發:系統服務理論詳解

系統服務的啟動 基本可以認為&#xff1a;OpenHarmony 的系統服務進程都是“由 init 直接或間接拉起”的。 直接方式&#xff1a; init 按 /system/etc/init/.cfg 啟動可執行&#xff08;如 /system/bin/sa_main、/system/bin/samgr 等&#xff09;&#xff0c;這些進程的 PPid…

龍虎榜——20250909

上證指數今天縮量收陰線&#xff0c;跌破10日均線&#xff0c;目前日線總體處于高位寬幅震蕩中&#xff0c;小級別暫未明確方向&#xff0c;指數面臨方向選擇&#xff0c;需要注意高位股的風險。 深證指數今天縮量收陰線&#xff0c;跌破5日均線&#xff0c;接下來幾天方向的選…

基于dijkstra算法的WSN網絡MAC協議matlab仿真,分析網絡延遲與網絡開銷

目錄 1.程序功能描述 2.測試軟件版本以及運行結果展示 3.部分程序 4.算法理論概述 5.完整程序 1.程序功能描述 無線傳感器網絡&#xff08;WSN, Wireless Sensor Network&#xff09;是由大量低成本、低功耗的傳感器節點組成&#xff0c;通過無線通信實現數據采集、傳輸與…

ES數據庫啟動時可以設置1G一下內存嗎

可以&#xff0c;但強烈不建議在生產環境中這樣做。ES 7.0 版本確實可以設置小于 1GB 的堆內存&#xff0c;但這會帶來嚴重的性能問題和穩定性風險。 快速回答 # 最小化配置示例 - 僅用于測試或開發環境 export ES_JAVA_OPTS"-Xms512m -Xmx512m" ./bin/elasticsearch…

TI-92 Plus計算器:單位換算功能介紹

1 TI-92 Plus計算器&#xff1a;單位換算功能介紹 TI-92 Plus 內置了全面的單位換算功能&#xff0c;支持長度、質量、時間、溫度、面積、體積、速度等數十種物理量的單位轉換&#xff0c;操作直觀&#xff0c;無需手動輸入換算系數。以下是具體使用方法、示例及功能特點&#…

雪球科技Java開發工程師筆試題

單選 1.下列哪些語句關于內存回收的說明是正確的?( C ) A.內存回收程序允許程序員直接釋放內存 B.程序員必須創建一個線程來釋放內存 C.內存回收程序負責釋放無用內存 D.內存回收程序可以在指定的時間釋放內存對象 2.以下哪項不是Java基礎類型(A) A.String B.int C.b…

NV3041A-01芯片屏幕

1. 核心概覽這是一款集成了電源管理、顯示內存&#xff08;RAM&#xff09;、時序控制等多種功能的單片顯示驅動芯片&#xff08;通常稱為Driver IC&#xff09;。它采用COG&#xff08;Chip-On-Glass&#xff09; 工藝&#xff0c;直接將芯片綁定在玻璃基板上&#xff0c;使得…

aiagent知識點

一、MCP (Model Context Protocol) 1. 核心概念是什么&#xff1a;MCP是一個開放協議&#xff0c;用于在應用&#xff08;如IDE、Agent&#xff09; 和工具/數據源&#xff08;如服務器、數據庫&#xff09; 之間建立標準化的通信。目標&#xff1a;解決AI工具生態的碎片化問題…

第2節-過濾表中的行-WHERE

摘要&#xff1a;在本教程中&#xff0c;您將學習如何使用 PostgreSQL 的 WHERE 子句來篩選表中的行。 PostgreSQL WHERE 子句 SELECT FROM 語句從表中所有行的一個或多個列中查詢數據。實際上&#xff0c;你經常需要選擇滿足某個條件的行。 要根據條件從表中篩選行&#xf…

IACheck賦能AI環評報告審核,推動環保設備制造行業發展

在“雙碳目標”和綠色制造的背景下&#xff0c;環保設備制造行業正在迎來快速發展。然而&#xff0c;環評報告作為項目合規的“通行證”&#xff0c;卻一直是企業最頭疼的環節之一&#xff1a;編寫復雜、審核周期長、錯誤率高。傳統的審核模式不僅耗時耗力&#xff0c;還容易出…

常見的多態

一、核心概念多態&#xff08;Polymorphism&#xff09; 的字面意思是“多種形態”。在Java中&#xff0c;它指的是&#xff1a;同一個行為&#xff08;方法&#xff09;具有多個不同表現形式或形態的能力。更具體地說&#xff0c;它允許你&#xff1a;父類的引用指向子類的對象…

20250909_排查10.1.1.190檔案庫房綜合管理系統20250908備份缺失問題+優化scp腳本(把失敗原因記錄進日志)并測試腳本執行情況

目錄 一、現象(圖中現象) 二、可能原因 1、本地源文件沒生成(最可能原因) 2、清理邏輯誤刪 三、時間同步檢查 1、運行命令查看當前時間源:w32tm /query /source 2、修改為內網 NTP 服務器 10.1.10.251: 四、腳本優化 1、scp.bat vs roboscp.bat 對比表 2、robo…

OpenHarmony之有源NFC-connected_nfc_tag模塊詳解

1. 模塊概述 Connected NFC Tag模塊是OpenHarmony NFC子系統的一部分,專門用于處理有源NFC標簽的讀寫操作。與基礎NFC模塊不同,該模塊專注于與已連接的有源NFC標簽進行交互,提供更高層次的API供應用層使用。 設備必須具備有源NFC標簽芯片,才能使用有源NFC標簽的讀和寫服務…