日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程语言 > c/c++ >内容正文

c/c++

C++——lambda表达式

發(fā)布時(shí)間:2023/12/13 c/c++ 39 豆豆
生活随笔 收集整理的這篇文章主要介紹了 C++——lambda表达式 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

介紹

lambda表達(dá)式是一種局部類類型,它含有一個(gè)構(gòu)造函數(shù),和一個(gè)const成員函數(shù)operator()()。

lambda表達(dá)式除了能做參數(shù)外,還能用于初始化一個(gè)聲明為auto或者std::function<R(LA)>的變量。R是lambda的返回類型,LA是它的類型參數(shù)列表。

組成部件

  • 一個(gè)可能為空的捕獲列表,指明定義環(huán)境中哪些名字能夠被用在lambda表達(dá)式中,以及這些名字是被拷貝還是引用。捕獲列表位于[]中。 補(bǔ)充: 靜態(tài)變量不能也不需要被捕獲。
  • 一個(gè)可選的參數(shù)列表。指明所需要的參數(shù),位于()中。補(bǔ)充 當(dāng)無(wú)參數(shù)時(shí),可以省略。
  • 一個(gè)可選的mutable修飾符,當(dāng)需要修改通過(guò)值捕獲的變量的副本時(shí),位于()之后。
  • 一個(gè)可選的noexcept修飾符,表明無(wú)異常被拋出。位于mutable修飾符之后。
  • 一個(gè)可選的->形式的返回類型聲明,可與decltype一起搭配使用。
  • 一個(gè)表達(dá)式體,指明要執(zhí)行的代碼,位于{}塊中。
  • 實(shí)現(xiàn)模型

    對(duì)于lambda表達(dá)式而言,有著很多種表述方法,并且有著多中優(yōu)化途徑。如果把lambda表達(dá)式看成是一種定義并使用函數(shù)對(duì)象的便捷方式,那么便于理解。

    假設(shè)有這么一個(gè)例子:

    void print_modulo(const vector<int>& v, ostream& os, int m) {for_each(begin(v), end(v),[&os, m](int x) {if (x % m == 0) os << x << '/n';}); }

    我們可以將其中的lambda表達(dá)式改寫成一個(gè)函數(shù)對(duì)象:

    class Modulo_print {ostream& os;int m; public :Modulo_print(ostream& s, int mm) :os{ s }, m{ mm } {}void operator() (int x) const {if (x % m == 0) os << x << '/n';} };

    并且改寫之前的例子:

    void print_modulo(const vector<int>& v, ostream& os, int m) {for_each(begin(v), end(v),Modulo_print{os, m}); }

    我們把由lambda表達(dá)式生成的函數(shù)對(duì)象稱為閉包對(duì)象 (閉包)

    如果lambda表達(dá)式通過(guò)引用 ([&]) 捕獲它定義環(huán)境中的每一個(gè)局部變量,則其閉包對(duì)象則可以優(yōu)化為簡(jiǎn)單的包含一個(gè)指向外層棧框架的指針。

    捕獲

    lambda表達(dá)式的主要用途是封裝一部分代碼以便將其用做參數(shù)。

    有些lambda表達(dá)式無(wú)需訪問(wèn)它的局部環(huán)境,這樣lambda表達(dá)式使用空引入符 [ ] 定義。

    lambda引入符的形式有很多:

  • [ ]空捕獲列表,在lambda表達(dá)式內(nèi)部無(wú)法使用其外層上下文中的任何局部名字,其數(shù)據(jù)需要從實(shí)參或者非局部變量中獲得。
  • [&]通過(guò)引用隱式捕獲。所有局部變量通過(guò)引用使用。
  • [=]通過(guò)值隱式捕獲。所有局部變量通過(guò)拷貝使用,這些副本是在lambda表達(dá)式的調(diào)用點(diǎn)獲得的。
  • [捕獲列表] 顯式捕獲。通過(guò)引用或者值方式捕獲其局部變量。捕獲列表中可以出現(xiàn)this (通過(guò)值方式捕獲) 和 緊跟…的名字以表示的元素。
  • [&, 捕獲列表] 對(duì)于出現(xiàn)在捕獲列表中的名字以值方式捕獲,不能以&為名字前綴。捕獲列表可以出現(xiàn)this。
  • [=, 捕獲列表] 對(duì)于出現(xiàn)在捕獲列表中的名字以引用方式捕獲,必須以&為前綴,捕獲列表中不能出現(xiàn)this。
  • 對(duì)于lambda表達(dá)式來(lái)說(shuō),當(dāng)把lambda傳遞給另一個(gè)線程時(shí),用值捕獲更優(yōu),通過(guò)引用或者指針訪問(wèn)其他線程中的內(nèi)容是一種危險(xiǎn)操作,對(duì)于性能和正確性來(lái)說(shuō)都是如此。

    對(duì)于可變模板參數(shù)的捕獲示例:

    template <typename...Var> void algo(int s, Var... var) { auto helper = [&s, &var...]{return s * (h1(var...) + h2(var...)); }; }

    生命周期

    lambda表達(dá)式的生命周期可能比它的被調(diào)用者更長(zhǎng)。當(dāng)我們把lambda表達(dá)式傳遞給另一個(gè)線程或者存在別處以供后續(xù)使用的時(shí)候。
    例如:

    void setup(Menu& m) { Point p1, p2, p3; m.add("draw a triangle", [&]{m.draw(p1, p2, p3); }); //可能會(huì)發(fā)生程序錯(cuò)誤 }

    當(dāng)setup完成之后,我們可能需要畫一個(gè)三角型,此時(shí)lambda表達(dá)式將會(huì)訪問(wèn)一個(gè)已經(jīng)不存在的局部變量。

    如果我們發(fā)現(xiàn)一個(gè)lambda表達(dá)式的生命周期可能比它的調(diào)用者更長(zhǎng),則我們需要確保所有局部信息都已經(jīng)被拷貝到閉包對(duì)象中去。

    m.add("draw a triangle", [=]{m.draw(p1, p2, p3); });

    lambda與this

    當(dāng)lambda表達(dá)式被用在成員函數(shù)當(dāng)中,我們?cè)鯓尤ピL問(wèn)類成員變量呢?我們通過(guò)捕獲this指針來(lái)訪問(wèn)類成員對(duì)象。
    例如:

    template <typename T> class Request {typedef typename vector<T>::value_type result;function<result(const vector<T>&)> oper;vector<T> values;result results; public:void execute(){[this] {results = oper(values);};} };

    類成員變量是通過(guò)this訪問(wèn)的,在lambda表達(dá)式中[this] 和 [=] 互不兼容,因此一不小心就可能在多線程程序中造成競(jìng)爭(zhēng)條件。

    mutable的lambda表達(dá)式

    如果希望在lambda表達(dá)式修改函數(shù)對(duì)象的狀態(tài),即修改通過(guò)值捕獲的變量,則可以使用mutable修飾符:

    void algo() {int count = 100;[count]()mutable {return --count;}; }

    lambda表達(dá)式與返回類型

    lambda表達(dá)式的大多數(shù)規(guī)則都是從類和函數(shù)借鑒過(guò)來(lái)的,然而需要有兩點(diǎn)需要注意:

  • 如果lambda表達(dá)式不需要任何參數(shù),則參數(shù)列表可以省略。因此lambda表達(dá)式的最簡(jiǎn)形式是[]{}。
  • lambda表達(dá)式的返回類型可以有其本身推斷得到,而函數(shù)(方法)不行。
  • 如果在一條lambda表達(dá)式的主體部分不包含return語(yǔ)句,則其返回類型為void。
    如果lambda表達(dá)式包含一條return語(yǔ)句,則返回類型是return表達(dá)式的類型。 其他情況,必須顯式定義一個(gè)返回類型。

    lambda表達(dá)式的類型

    任意兩個(gè)lambda表達(dá)式的類型都不相同,一旦兩個(gè)lambda表達(dá)式的類型相同,則模板實(shí)例化機(jī)制就無(wú)法識(shí)別它們了。

    例如:

    auto algo = [&algo](char* b, char* a) {swap(*b, *--a); algo(++b, a);};

    由于algo的類型并沒(méi)有在使用之前被推斷出來(lái),因此上面的寫法是錯(cuò)誤的。

    使用function包裝器可以存入函數(shù)對(duì)象。就可以保證,在使用之前, algo的類型就已經(jīng)知道了。

    function<void (char*b, char*a)> algo = [&](char* b, char* a) {swap(*b, *--a); algo(++b, a);};

    如果我們只是想給lambda表達(dá)式起個(gè)名字,而不會(huì)在主體內(nèi)部遞歸的使用它。則:

    auto algo = [&](char* b, char* a) {swap(*b, *--a); };

    是沒(méi)有問(wèn)題的。

    如果lambda表達(dá)式什么也不捕獲,則我們可以把它賦值給一個(gè)指向正確類型的函數(shù)指針。

    double (*fun) (double a) = [](double a) {return sqrt(a);};

    但行好事, 莫問(wèn)前程!

    總結(jié)

    以上是生活随笔為你收集整理的C++——lambda表达式的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

    如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。

    主站蜘蛛池模板: 茄子av| 人成在线视频 | 婷婷综合久久 | 中文字幕免费高清在线观看 | 四虎午夜影院 | av片在线免费观看 | 午夜18视频在线观看 | 豆花视频成人 | 日本三级视频网站 | 天堂在线中文字幕 | 伊人一级片 | 国产在线视频你懂得 | 国产精品久久999 | 美女二区| 麻豆视频在线免费观看 | 亚洲欧美高清 | 午夜操操| 麻豆蜜桃wwww精品无码 | 天天摸天天做天天爽水多 | 国产精品亚洲lv粉色 | 狠狠操综合| 久久亚洲无码视频 | 日本伦理一区二区 | 日韩精品一区二区在线视频 | 欧美熟妇交换久久久久久分类 | 亚洲精品色图 | 一区二区三区视频免费观看 | 夜夜cao| 国产操人 | 宅男av| 狂野欧美性猛交免费视频 | 综合视频一区 | 老牛影视av一区二区在线观看 | 男女瑟瑟网站 | 天堂网91| 加勒比成人在线 | 欧美成人hd | 欧洲高潮三级做爰 | 国产欧美日本在线 | 欧美日韩亚洲不卡 | 成年人在线视频网站 | 丁香六月天婷婷 | 日韩欧美一区二区区 | 日韩99 | 中文字幕在线观看线人 | 午夜色福利| 激情五月亚洲 | 97影院在线午夜 | 日本精品视频在线 | 久久观看 | av电影在线不卡 | 拔插拔插海外华人永久免费 | 久久精品成人一区二区三区蜜臀 | 日本男人的天堂 | 国产成人无码一区二区三区在线 | 免费无码不卡视频在线观看 | 亚洲天堂2014 | 中文字幕有码视频 | av免费在线网站 | 成人免费视频a | 视频久久 | 亚洲AV乱码国产精品观看麻豆 | 丁香花在线影院观看在线播放 | 国产精品美女www | 91porny在线 | 一区二区国产在线观看 | 亚洲午夜久久久久久久久久久 | 日韩久久精品电影 | 麻豆网 | 国产伦精品一区二区三区高清 | 国产热99| 国产色网址 | 精品人妻一区二区三区久久嗨 | 老司机一区二区三区 | 精品久久久无码中文字幕边打电话 | 欧美精品999| 国产又大又粗又硬 | 成人午夜一区二区 | 日批的视频 | 亚洲精品乱码久久久久久蜜桃图片 | 日韩淫视频 | 亚洲一区二区电影网 | 天堂在线观看 | 国产aaaaaaa | 麻豆传谋在线观看免费mv | 成长快手短视频在线观看 | 69视频在线看 | 久久久久青草 | 欧美日韩高清在线观看 | 在线男人天堂 | 韩国美女av| 欧美日韩亚洲国产一区 | 欧美成人高潮一二区在线看 | 福利视频在线 | 国产精品蜜 | 国产精品综合一区二区 | 欧美日韩一区二区三 | 加勒比久久综合 | 污视频大全|