亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > C++ > 正文

C++11新特性:Lambda表達式

2019-11-06 07:12:08
字體:
來源:轉載
供稿:網友

轉自:https://www.devbean.net/2012/05/cpp11-lambda/

或許,Lambda 表達式算得上是 C++ 11 新增特性中最激動人心的一個。這個全新的特性聽起來很深奧,但卻是很多其他語言早已提供(比如 C#)或者即將提供(比如 java)的。簡而言之,Lambda 表達式就是用于創建匿名函數的。GCC 4.5.x 和 Microsoft Visual Studio 早已提供了對 lambda 表達式的支持。在 GCC 4.7 中,默認是不開啟 C++ 11 特性的,需要添加 -std=c++11 編譯參數。而 VS2010 則默認開啟。

為什么說 lambda 表達式如此激動人心呢?舉一個例子。標準 C++ 庫中有一個常用算法的庫,其中提供了很多算法函數,比如 sort() 和 find()。這些函數通常需要提供一個“謂詞函數 PRedicate function”。所謂謂詞函數,就是進行一個操作用的臨時函數。比如 find() 需要一個謂詞,用于查找元素滿足的條件;能夠滿足謂詞函數的元素才會被查找出來。這樣的謂詞函數,使用臨時的匿名函數,既可以減少函數數量,又會讓代碼變得清晰易讀。

下面來看一個例子:

#include <algorithm>#include <cmath>void abssort(float *x, unsigned N){ std::sort(x, x + N, [](float a, float b) { return std::abs(a) < std::abs(b); });}

從上面的例子來看,盡管支持 lambda 表達式,但 C++ 的語法看起來卻很“神奇”。lambda 表達式使用一對方括號作為開始的標識,類似于聲明一個函數,只不過這個函數沒有名字,也就是一個匿名函數。這個匿名函數接受兩個參數,a和b;其返回值是一個 bool 類型的值,注意,返回值是自動推斷的,不需要顯式聲明,不過這是有條件的!條件就是,lambda 表達式的語句只有一個 return。函數的作用是比較 a、b 的絕對值的大小。然后,在此例中,這個 lambda 表達式作為一個閉包被傳遞給 std::sort() 函數。

下面,我們來詳細解釋下這個神奇的語法到底代表著什么。

我們從另外一個例子開始:

std::cout << [](float f) { return std::abs(f); } (-3.5);

輸出值是什么?3.5!注意,這是一個函數對象(由 lambda 表達式生成),其實參是 -3.5,返回值是參數的絕對值。lambda 表達式的返回值類型是語言自動推斷的,因為std::abs()的返回值就是 float。注意,前面我們也提到了,只有當 lambda 表達式中的語句“足夠簡單”,才能自動推斷返回值類型。

C++ 11 的這種語法,其實就是匿名函數聲明之后馬上調用(否則的話,如果這個匿名函數既不調用,又不作為閉包傳遞給其它函數,那么這個匿名函數就沒有什么用處)。如果你覺得奇怪,那么來看看 JavaScript 的這種寫法:

function() {} ();function(a) {} (-3.5);

C++ 11 的寫法完全類似 Javascript 的語法。

如果我不想讓 lambda 表達式自動推斷類型,或者是 lambda 表達式的內容很復雜,不能自動推斷怎么辦?比如,std::abs(float)的返回值是 float,我想把它強制轉型為 int。那么,此時,我們就必須顯式指定 lambda 表達式返回值的類型:

std::cout << [](float f) -> int { return std::abs(f); } (-3.5);

這個語句與前面的不同之處在于,lambda 表達式的返回時不是 float 而是 int。也就是說,上面語句的輸出值是 3。返回值類型的概念同普通的函數返回值類型是完全一樣的。

當我們想引用一個 lambda 表達式時,我們可以使用auto關鍵字,例如:

auto lambda = [] () -> int { return val * 100; };

auto關鍵字實際會將 lambda 表達式轉換成一種類似于std::function的內部類型(但并不是std::function類型,雖然與std::function“兼容”)。所以,我們也可以這么寫:

std::function<int()> lambda = [] () -> int { return val * 100; };

如果你對std::function

float f0 = 1.0;std::cout << [=](float f) { return f0 + std::abs(f); } (-3.5);

其輸出值是 4.5。[=] 意味著,lambda 表達式以傳值的形式捕獲同范圍內的變量。另外一個例子:

float f0 = 1.0;std::cout << [&](float f) { return f0 += std::abs(f); } (-3.5);std::cout << '/n' << f0 << '/n';

輸出值是 4.5 和 4.5。[&] 表明,lambda 表達式以傳引用的方式捕獲外部變量。那么,下一個例子:

float f0 = 1.0;std::cout << [=](float f) mutable { return f0 += std::abs(f); } (-3.5);std::cout << '/n' << f0 << '/n';

這個例子很有趣。首先,[=]意味著,lambda 表達式以傳值的形式捕獲外部變量。C++ 11 標準說,如果以傳值的形式捕獲外部變量,那么,lambda 體不允許修改外部變量,對 f0 的任何修改都會引發編譯錯誤。但是,注意,我們在 lambda 表達式前聲明了mutable關鍵字,這就允許了 lambda 表達式體修改 f0 的值。因此,我們的例子本應報錯,但是由于有 mutable 關鍵字,則不會報錯。那么,你會覺得輸出值是什么呢?答案是,4.5 和 1.0。為什么 f0 還是 1.0?因為我們是傳值的,雖然在 lambda 表達式中對 f0 有了修改,但由于是傳值的,外部的 f0 依然不會被修改。

上面的例子是,所有的變量要么傳值,要么傳引用。那么,是不是有混合機制呢?當然也有!比如下面的例子:

float f0 = 1.0f;float f1 = 10.0f;std::cout << [=, &f0](float a) { return f0 += f1 + std::abs(a); } (-3.5);std::cout << '/n' << f0 << '/n';

這個例子的輸出是 14.5 和 14.5。在這個例子中,f0 通過引用被捕獲,而其它變量,比如 f1 則是通過值被捕獲。

下面我們來總結下所有出現的 lambda 引入符:

[] // 不捕獲任何外部變量[=] // 以值的形式捕獲所有外部變量[&] // 以引用形式捕獲所有外部變量 [x, &y] // x 以傳值形式捕獲,y 以引用形式捕獲 [=, &z]// z 以引用形式捕獲,其余變量以傳值形式捕獲 [&, x] // x 以值的形式捕獲,其余變量以引用形式捕獲

另外有一點需要注意。對于[=]或[&]的形式,lambda 表達式可以直接使用 this 指針。但是,對于[]的形式,如果要使用 this 指針,必須顯式傳入:.

[this]() { this->someFunc(); }();

至此,我們已經大致了解了 C++ 11 提供的 lambda 表達式的概念。建議通過結合 lambda 表達式與std::sort()或std::for_each()這樣的標準函數來嘗試使用一下吧!


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表

圖片精選

亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
亚洲最大av网| 亚洲小视频在线| 国产啪精品视频| 日韩69视频在线观看| 国产精品入口免费视频一| 精品国产一区二区三区久久久狼| 日韩在线中文视频| 国产日韩换脸av一区在线观看| 国产精品入口日韩视频大尺度| 日韩综合中文字幕| 日韩最新在线视频| 8x拔播拔播x8国产精品| 91精品国产高清久久久久久| 在线日韩av观看| 国产日韩欧美电影在线观看| 亚洲精品91美女久久久久久久| 亚洲综合国产精品| 91网站免费看| 久久精品在线播放| 久久精品国产96久久久香蕉| 久久综合伊人77777尤物| 色综合久久88色综合天天看泰| 国产91九色视频| 91精品国产综合久久香蕉| 欧美猛交免费看| 成人精品在线观看| 亚洲国产另类久久精品| 欧美激情视频三区| 成人欧美在线视频| 日韩美女免费视频| 懂色av影视一区二区三区| 精品视频久久久| 最近2019年日本中文免费字幕| 国语自产偷拍精品视频偷| 欧美一区二区影院| 久久不射热爱视频精品| www.欧美免费| 国产一区香蕉久久| 91精品在线观| 97久久久免费福利网址| 日韩免费观看av| 国产精品wwwwww| 亚洲欧美成人一区二区在线电影| 国产欧美亚洲精品| 日韩精品在线观看一区二区| 国产精品一区二区3区| xvideos亚洲人网站| 国产精品高潮呻吟久久av野狼| 97香蕉超级碰碰久久免费的优势| 一区三区二区视频| 97色在线视频观看| 在线免费看av不卡| 国产在线高清精品| 色综合久久悠悠| 色七七影院综合| 欧美在线一区二区视频| 国内精品中文字幕| 久热精品在线视频| 久久激情视频免费观看| 综合欧美国产视频二区| 欧美国产第二页| 欧美精品在线观看91| 日韩中文字幕国产| 中文字幕九色91在线| 久久精品国产69国产精品亚洲| 亚洲免费人成在线视频观看| 欧美成人免费一级人片100| 国产z一区二区三区| www亚洲精品| 国产精品视频久久久久| 亚洲最大成人网色| 中文字幕日韩精品在线| 欧美资源在线观看| 国产精品女人久久久久久| 亚洲黄在线观看| 91av网站在线播放| 国产精品偷伦一区二区| 亚洲第一区在线观看| 91网站在线看| 国产视频自拍一区| 成人黄在线观看| 97久久精品视频| 另类图片亚洲另类| 91在线网站视频| 亚洲天堂av女优| 中文字幕欧美国内| 国产精品美女久久久免费| 精品久久香蕉国产线看观看亚洲| 国产精自产拍久久久久久蜜| 日韩精品日韩在线观看| 国产精品久久久久久久av电影| 久久久久久亚洲精品中文字幕| 日本三级韩国三级久久| 亚洲国产97在线精品一区| 亚洲精品国产品国语在线| 热99精品里视频精品| 成人黄色免费网站在线观看| 欧美麻豆久久久久久中文| 亚洲国产精品99| 国产网站欧美日韩免费精品在线观看| 欧美日韩国产一区在线| 成人黄色网免费| 欧美性猛交99久久久久99按摩| 亚洲综合一区二区不卡| 2021国产精品视频| 精品视频中文字幕| 浅井舞香一区二区| 日韩电影免费在线观看中文字幕| 美日韩精品视频免费看| 亚洲欧美资源在线| 国产美女精品视频免费观看| 日韩福利在线播放| 欧美电影免费在线观看| 91成人在线观看国产| 欧美日韩日本国产| 欧美午夜性色大片在线观看| 成人精品在线观看| 欧美激情a∨在线视频播放| 日本精品久久电影| 欧美理论片在线观看| 欧美性感美女h网站在线观看免费| 久久免费国产视频| 日韩国产精品视频| 51ⅴ精品国产91久久久久久| 日韩精品一区二区视频| 久久久亚洲欧洲日产国码aⅴ| 久久视频精品在线| www.99久久热国产日韩欧美.com| 日本精品久久电影| 亚洲老司机av| 日韩欧美国产免费播放| 91国产精品91| 日韩欧美亚洲成人| 国产精品一区二区三区成人| 青青草国产精品一区二区| 国产噜噜噜噜噜久久久久久久久| 欧美亚洲国产日韩2020| 97在线日本国产| 国产视频欧美视频| 日韩欧美高清在线视频| 亚洲精品欧美日韩专区| 成人免费视频在线观看超级碰| 另类天堂视频在线观看| 亚洲视频在线免费观看| 国产拍精品一二三| 国产精品第3页| 精品久久久久久久久久国产| 久久视频免费在线播放| 国产脚交av在线一区二区| 国产视频在线一区二区| 青青草成人在线| 久热爱精品视频线路一| 久久夜色精品亚洲噜噜国产mv| 欧美大尺度在线观看| 国产在线视频不卡| 亚洲自拍欧美色图| 最新日韩中文字幕| 高清欧美电影在线| 美女福利精品视频| 亚洲va国产va天堂va久久| 亚洲精品中文字幕女同| 欧美福利在线观看| 欧美高清在线视频观看不卡| 欧美刺激性大交免费视频|