32 lambda表達式

c++11

c++98例子

在c++98中,如果想要對一個數據集合中的元素進行排序,可以適用std::sort方法

#include <algorithm>#include <functional>int main(){int array[] = {4,1,8,5,3,7,0,9,2,6};// 默認按照小于比較,排出來結果是升序
std::sort(array, array+sizeof(array)/sizeof(array[0]));// 如果需要降序,需要改變元素的比較規則
std::sort(array, array + sizeof(array) / sizeof(array[0]), greater<int>());return 0;}

如果待排序是自定義類型,需要用戶定義排序時的比較規則:

struct Goods
{string _name;  // 名字double _price; // 價格int _evaluate; // 評價//...Goods(const char* str, double price, int evaluate):_name(str), _price(price), _evaluate(evaluate){}
};//價格升序
struct ComparePriceLess
{bool operator()(const Goods& gl, const Goods& gr){return gl._price < gr._price;}
};struct ComparePriceGreater
{bool operator()(const Goods& gl, const Goods& gr){return gl._price > gr._price;}
};int main()
{vector<Goods> v = { { "蘋果", 2.1, 5 }, { "香蕉", 3, 4 }, { "橙子", 2.2, 3 }, { "菠蘿", 1.5, 4 } };sort(v.begin(), v.end(), ComparePriceLess());sort(v.begin(), v.end(), ComparePriceGreater());return 0;
}

隨著c++語法的發展,上面的寫法太復雜了,為了實現一個algorithm算法,都要重新去寫一個類,如果每次比較的邏輯不一樣,還要去實現多個類,特別是相同類的命名,這些都給我編程者帶來極大的不便。因此,在c++11語法中出現了lambda表達式

lambda表達式

 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; });sort(v.begin(), v.end(), [](const Goods& g1, const Goods& g2){return g1._evaluate < g2._evaluate; });sort(v.begin(), v.end(), [](const Goods& g1, const Goods& g2){return g1._evaluate > g2._evaluate; });

上述代碼是使用c++11中的lambda表達式解決,可以看出lambda實際是一個匿名函數

打印出類型:

auto f1 = [](int x)->int { return 0; };
f1(1);
cout << typeid(f1).name() << endl;

// // class <lambda_ba37a3eb9b8e2495e3aae6ef76d9eed2>
// // <lambda_uuid>
vs2019是上面的類型,lambda加uuid格式
在這里插入圖片描述vs2022
在這里插入圖片描述

lambda表達式語法

格式:capture-list mutable ->return type {statement}
1.lambda表達式各部分說明

  • [capture-list]:捕捉列表,該列表總是出現在lambda函數的開始位置,編譯器根據{}來判斷接下來的代碼是否為lambda函數,捕捉雷彪能夠捕捉上下文中的變量供lambda函數使用
  • (parameters):參數列表。與普通函數的參數列表一致,如果不需要參數傳遞,可以連同()一起省略
  • mutable:默認情況下,lambda函數總是一個const函數,mutable可以取消其常量性。使用該修飾符時,參數雷彪不可省略(即使參數為空)
  • ->returntype:返回值類型。追蹤返回類型形式生命函數的返回值類型,沒有返回值時此部分可省略。返回值類型明確情況下,可以省略,由編譯器對返回類型推導
  • {statement}:函數體。在該函數體內,除了可以適用其參數外,還可以使用所有捕獲到的變量

注意:
在lambda函數定義中,參數列表和返回值類型都是可選部分,而捕捉列表和函數體可以為空。因此c++11中最簡單的lam函數為:[]{},不做任何事情

//最簡單的lambda表達式,沒有意義
[] {};
//省略參數列表和返回值類型,返回值類型由編譯器推導為int
int a = 3, b = 4;
[=] {return a + 3; };
//省略返回值類型,無返回值
auto fun1 = [=](int c) { c = a + b; };
//各部分都完善
auto fun2 = [=](int c)->int { return c = a + b; };

通過上述例子可以看出,lambda比倒是實際上可以理解為無名函數,該函數無法直接調用,如果想要調用,可借助auto將其賦值給一個變量

2.捕獲列表說明
捕捉列表描述了上下文中那些數據可以被lambda使用,以及使用的方式傳值還是傳引用

  • [var]:表示值傳遞方式捕捉變量var
  • [=]:值傳遞方式捕捉所有父作用域的變量(包括this)
  • [&var]:表示引用傳遞捕捉變量var
  • [&]:表示引用傳遞捕捉所有父作用域的變量(包括this)
  • [this]:表示值傳遞方式捕捉當前的this指針

注意:
a.父作用域指包含lambda函數的語句塊
b.語法上捕捉列表可由多個捕捉項組成,并以逗號分割
比如:[=,&a,&b]:以引用傳遞的方式捕捉變量a和b,值傳遞方式捕捉其他所有變量
[&, a, this]:值傳遞方式捕捉變量a和this,引用方式捕捉其他變量

class AA
{
public:void func(){/*auto f1 = [this]() {cout << a1 << endl;cout << a2 << endl;};*/auto f1 = [=]() {cout << a1 << endl;cout << a2 << endl;};f1();}
private:int a1 = 1;int a2 = 1;
};

c.捕捉雷彪不允許變量重復傳遞,否則就會導致編譯錯誤
比如:[=,a]:=已經以值傳遞方式捕捉了所有變量,捕捉a重復
d.在塊作用域外的lambda函數捕捉列表必須為空
e。在塊作用域中的lambda函數不僅能捕捉父作用域的局部變量,不會做任何非此作用域或者非局部變量都會導致編譯錯誤
f.lambda表達式之間不能互相賦值,即使看起來類型相同

void (*PF)();int main(){auto f1 = []{cout << "hello world" << endl; };auto f2 = []{cout << "hello world" << endl; };// 此處先不解釋原因,等lambda表達式底層實現原理看完后,大家就清楚了
//f1 = f2;    // 編譯失敗--->提示找不到operator=()// 允許使用一個lambda表達式拷貝構造一個新的副本
auto f3(f2);f3();
// 可以將lambda表達式賦值給相同類型的函數指針
PF = f2;PF();return 0;}
//值捕捉不能更改
int x = 0, y = 1;
auto f1 = [x, y]() {int tmp = x;x = y;y = tmp;};

上面捕捉的x和y和聲明的xy不是同一個,值傳遞不能更改,lam默認是const的。需要加mutable關鍵字,但因為不是同一個值,不能實現交換

int x = 0, y = 1;
auto f1 = [x, y]() mutable {int tmp = x;x = y;y = tmp;};

函數對象和lambda表達式

函數對象,又稱仿函數,可以像函數一樣使用的對象,就是在類中重載operator()運算符的類對象

class Rate{public:Rate(double rate): _rate(rate){}double operator()(double money, int year){ return money * _rate * year;}private:double _rate;};int main(){// 函數對象
double rate = 0.49;Rate r1(rate);r1(10000, 2);// lamberauto r2 = [=](double monty, int year)->double{return monty*rate*year; 
};r2(10000, 2);return 0;}

從使用方式上看,函數對象與lambda表達式完全一樣
函數對象將rate作為其成員變量,在定義對象時給出初始值即可,lambda表達式通過捕獲列表可以直接將該變量捕獲到
在這里插入圖片描述
實際在底層編譯器對于lambda表達式的處理方式,完全是按照函數對象處理。如果定義了一個lambda表達式,編譯器會自動生成一個類,重載()

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

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

相關文章

Django + Vue 實現圖片上傳功能的全流程配置與詳細操作指南

文章目錄 前言圖片上傳步驟1. urls 配置2. settings 配置3. models 配置4. 安裝Pillow 前言 在現代Web應用中&#xff0c;圖片上傳是一個常見且重要的功能。Django作為強大的Python Web框架&#xff0c;結合Vue.js這樣的現代前端框架&#xff0c;能夠高效地實現這一功能。本文將…

【Arduino】小飛魚通達二開實驗ESP32使用紅外尋跡傳感器 (圖文)

在智能小車項目中都會有一個功能就是自動巡線&#xff0c;今天小飛魚通達來實驗的就是這個紅外尋跡傳感器。 紅外尋跡傳感器的原理就是有一個小燈發出紅外光&#xff0c;光線照到物體后進行反射&#xff0c;有一個接收器進行接收&#xff0c;當在一定距離內會導通電路&#xf…

網安加·百家講壇 | 肖文棣:鑄盾護企——面對勒索病毒產業鏈的企業防護之道

作者簡介&#xff1a;肖文棣&#xff0c;OWASP中國廣東分會負責人、網安加社區特聘專家&#xff0c;現任某外企安全架構師&#xff0c;負責應用安全設計、管理和評審等工作。 引言 隨著信息技術的飛速發展&#xff0c;網絡安全問題愈發凸顯&#xff0c;企業面臨的網絡安全威脅…

HarmonyOS NEXT Beta 版開發者及先鋒用戶招募(第一期)報名答題題庫(持續更新中,僅供學習分享使用)

判斷題 All True. 單選題 關于容器組件Row和Column&#xff0c;下面說法錯誤的是&#xff1a; A A. justifyContent用于設置子組件在交叉軸方向上的對齊格式。 B. Row容器主軸為水平方向&#xff0c;Column容器主軸為垂直方向。 C. justifyContent用于設置子組件在主軸方向上的…

瞎談指令集和寄存器讀寫來驅動硬件

文章目錄 前言一、到底什么是指令集&#xff1f;二、為什么現代CPU需要指令集&#xff1f;三、開發完指令集究竟有什么缺點&#xff1f;四、寄存器讀寫怎么驗證&#xff1f;總結 前言 其實很早以前就想對這個話題展開來聊聊&#xff0c;但是對體系結構的理解也僅僅限于《量化體…

應急響應:應急響應流程,常見應急事件及處置思路

「作者簡介」&#xff1a;冬奧會網絡安全中國代表隊&#xff0c;CSDN Top100&#xff0c;就職奇安信多年&#xff0c;以實戰工作為基礎著作 《網絡安全自學教程》&#xff0c;適合基礎薄弱的同學系統化的學習網絡安全&#xff0c;用最短的時間掌握最核心的技術。 這一章節我們需…

交通氣象站:保障道路暢通的守護者

隨著現代社會的飛速發展&#xff0c;交通網絡日益密集&#xff0c;人們的出行越來越依賴于公路、鐵路和航空等交通方式。然而&#xff0c;多變的天氣條件常常給交通安全帶來隱患&#xff0c;如大霧、雨雪、強風等惡劣天氣不僅影響行車視線&#xff0c;還可能造成路面濕滑、結冰…

在我們實際使用中,線程池的大小配置多少合適?

線程池的大小配置是一個需要根據具體應用場景和資源情況來決定的問題。沒有一個固定的數字適用于所有情況&#xff0c;但是可以遵循一些通用的原則和方法來確定合適的線程池大小&#xff0c;我們來看一下通用原則和方法都有哪幾個維度。 通用原則和方法 1. CPU密集型任務&…

第十四屆藍橋杯省賽C++B組D題【飛機降落】題解(AC)

解題思路 這道題目要求我們判斷給定的飛機是否都能在它們的油料耗盡之前降落。為了尋找是否存在合法的降落序列&#xff0c;我們可以使用深度優先搜索&#xff08;DFS&#xff09;的方法&#xff0c;嘗試所有可能的降落順序。 首先&#xff0c;我們需要理解題目中的條件。每架…

【MotionCap】pycharm 遠程在wsl2 ubuntu20.04中root的miniconda3環境

pycharm wsl2 鏈接到pycharmsbin 都能看到內容,/root 下內容賦予了zhangbin 所有,pycharm還是看不到/root 下內容。sudo 安裝了miniconda3 引發了這些問題 由于是在 root 用戶安裝的miniconda3 所以安裝路徑在/root/miniconda3 里 這導致了環境也是root用戶的,會觸發告警 WA…

沖擊試樣缺口拉刀V2U2U3U5

拉刀性能介紹 沖擊試樣缺口拉刀采用進口高速工具鋼W18Cr4V材質&#xff0c;特殊工藝精密加工制造&#xff0c;硬度高&#xff0c;耐磨性好&#xff0c;使用壽命長&#xff0c;每把拉刀可加工試樣達20&#xff0c;000多個。拉刀共54個齒&#xff08;深度5mm缺口拉刀為74個齒&am…

抖音本地生活服務商條件太高怎么辦?低門檻方法來了!

隨著本地生活賽道的潛力不斷顯現&#xff0c;本地生活服務商的數量也在與日俱增。而在所有開通本地生活服務板塊的互聯網平臺中&#xff0c;日活躍用戶數約8億的抖音往往是眾多創業者優先考慮的對象&#xff0c;以抖音本地生活服務商如何申請為代表的相關問題也因此常出現在多個…

排序算法(1)之插入排序----直接插入排序和希爾排序

個人主頁&#xff1a;C忠實粉絲 歡迎 點贊&#x1f44d; 收藏? 留言? 加關注&#x1f493;本文由 C忠實粉絲 原創 排序之插入排序----直接插入排序和希爾排序(1) 收錄于專欄【數據結構初階】 本專欄旨在分享學習數據結構學習的一點學習筆記&#xff0c;歡迎大家在評論區交流討…

頁面加載503 Service Temporarily Unavailable異常

最近發現網頁刷新經常503&#xff0c;加載卡主&#xff0c;刷新頁面就正常了。 研究之后發現是頁面需要的js文件等加載失敗了。 再研究之后發現是nginx配置的問題。 我之前為了解決一個漏洞檢測到目標主機可能存在緩慢的HTTP拒絕服務攻擊 把nginx的連接設置了很多限制&#…

PHP傳奇游戲推廣信息發布站程序源碼帶會員發布

這是一個游戲導航網站程序。可以做任何一款游戲的推廣發布&#xff0c;會員注冊發布&#xff0c;后臺審核通過&#xff0c;前臺就可以展示&#xff0c;非常不錯的游戲發布平臺

一個項目學習Vue3---響應式基礎

觀察下面一段代碼&#xff0c;學習響應式基礎的全部內容 <template><div><div>將下面的msg屬性放到上面來:{{ msg }}</div><button click"count">{{ count }}</button><button click"object.count.value">{{ o…

關于Autowired

Autowired 是 Spring Framework 中的一個注解&#xff0c;用于自動注入依賴對象。通過這個注解&#xff0c;Spring 可以自動將匹配的 bean 注入到所需的類中&#xff0c;從而實現控制反轉&#xff08;IoC&#xff09;和依賴注入&#xff08;DI&#xff09;。 基本用法 Autowi…

javascript: void(0);用法和常見問題

在JavaScript中&#xff0c;void(0)是一個表達式&#xff0c;它用來獲取一個特殊的值undefined&#xff0c;并且執行一個沒有返回值的操作。這個表達式經常用于創建一個沒有實際返回值的函數調用&#xff0c;或者在需要一個表達式的地方使用&#xff0c;但不希望有任何返回值。…

【Carsim】Carsim2019與Matlab2015b聯合仿真測試

&#x1f60f;★,:.☆(&#xffe3;▽&#xffe3;)/$:.★ &#x1f60f; 這篇文章主要介紹Carsim2019與Matlab2015b聯合仿真測試。 學其所用&#xff0c;用其所學。——梁啟超 歡迎來到我的博客&#xff0c;一起學習&#xff0c;共同進步。 喜歡的朋友可以關注一下&#xff0c…

HTML基礎知識學習指南

HTML基礎知識學習指南 1. 介紹 HTML&#xff08;超文本標記語言&#xff09;是構建網頁的基礎。它是一種標記語言&#xff0c;用于定義網頁的內容和結構。HTML由一系列元素組成&#xff0c;這些元素使用標簽來表示。 2. HTML文檔結構 HTML文檔的基本結構包括以下部分&#…