為什么引入Lambda
Lambda表達式是一個可以內(nèi)聯(lián)在我們代碼中的函數(shù),我們可以將他傳遞給另外一個函數(shù)。在沒有引入Lambda表達式之前,當我們遇到需要對多個數(shù)據(jù),按照同一規(guī)則進行操作的時候,創(chuàng)建機動函數(shù)會更簡單,但是必須在其他地方定義好該函數(shù),然后再使用它,有時候兩者之間可能距離離的很遠,想要了解該函數(shù)內(nèi)部操作的原理,需要翻閱多頁源代碼找它的定義,這樣使得代碼的可讀性大打折扣。這就是Lambda表達式出現(xiàn)的主要原因。
基本的Lambda語法
lambda表達式是一個匿名函數(shù)。其可以捕獲作用域中的變量。其在C++11中常用的語法如下:
[captures](params){body}
[captures]{body} //省略了形參列表,函數(shù)不接收實參,如同形參列表為()
[captures](params)- >return-type{body} //return-type為返回類型
//eg:
//捕獲列表 參數(shù)列表 函數(shù)體
[] (int a, int b) { return a < b;}
//捕獲列表 參數(shù)列表 返回類型 函數(shù)體
[] (double x) - > double {int y = x; return x - y;}
/*注:Lambda函數(shù)沒有聲明返回類型,其返回類型相當于使用decltyp根據(jù)返回值推斷得到的。
如果函數(shù)體內(nèi)不包含返回語句,則推斷出返回類型為void。
但是僅當函數(shù)體完全由一條返回語句組成時,自動類型推斷才管用
否則,需要使用新增的返回類型后置語法*/
【 注 :Lambda表達式自動推斷返回值類型:有些編譯器,像GCC,即使你有多于一個返回語句也不可以自動推斷成功,但標準不保證這一點,因此為了防止意外的發(fā)生,當函數(shù)體內(nèi)返回語句不止一條的時候,建議使用返回類型后置語法】
其中captures
為捕獲,它一個包含0個或者多個捕獲符的用逗號分隔的列表。params
為參數(shù)列表,body
為函數(shù)體。默認的捕獲符只有:
&
:采用引用隱式捕獲的方式使用自動變量=
:采用復制隱式捕獲的方式使用自動變量[] // 默認不捕獲 [&] // 默認以引用捕獲(意味著在函數(shù)體內(nèi)可以按照引用的方式使用Lambda表達式所在范圍內(nèi)所有可見的局部變量) [&, i] // 以引用捕獲(同上),但i以值捕獲 [=] // 默認以復制捕獲(意味著在函數(shù)體內(nèi)可以按照值傳遞的方式使用Lambda表達式所在范圍內(nèi)所有可見的局部變量) [=, &i] // 以復制捕獲(同上),但 i 以引用捕獲
下面我們通過C++ Primer Plus中的一個例子進一步理解Lambda表達式:
#include < iostream >
#include < vector >
#include < algorithm >
#include < cmath >
#include < ctime >
const long Size = 390000L;
int main()
{
using std::cout;
std::vector< int > numbers(Size);
std::srand(std::time(0));
std::generate(numbers.begin(), numbers.end(), std::rand);
cout < < "Sample size = " < < Size < < 'n';
// using lambdas
int count3 = std::count_if(numbers.begin(), numbers.end(),
[](int x){return x % 3 == 0;});
cout < < "Count of numbers divisible by 3: " < < count3 < < 'n';
int count13 = 0;
std::for_each(numbers.begin(), numbers.end(),
[&count13](int x){count13 += x % 13 == 0;});
cout < < "Count of numbers divisible by 13: " < < count13 < < 'n';
// using a single lambda
count3 = count13 = 0;
std::for_each(numbers.begin(), numbers.end(),
[&](int x){count3 += x % 3 == 0; count13 += x % 13 == 0;});
cout < < "Count of numbers divisible by 3: " < < count3 < < 'n';
cout < < "Count of numbers divisible by 13: " < < count13 < < 'n';
return 0;
}
程序輸出結(jié)果:
Sample size = 390000
Count of numbers divisible by 3: 130274
Count of numbers divisible by 13: 30009
Count of numbers divisible by 3: 130274
Count of numbers divisible by 13: 30009
Lambda與STL的結(jié)合
當STL中的算法(algorithms)庫遇到Lambda的時候,會碰出什么樣的火花呢?毋庸置疑,這極大的提高我們的編程效率,更提高了代碼的整潔性和可讀性,例如:
vector< int > v;
v.push_back(1);
v.push_back(2);
//不使用Lambda表達式
for ( auto itr = v.begin(); itr != v.end(); itr++ )
{
cout < < *itr;
}
//使用Lambda表達式
for_each( v.begin(), v.end(), [] (int val){cout < < val;} );
正如上面的例子,使用Lambda表達式后,代碼顯的更漂亮,而且它的可讀性也很強,結(jié)構(gòu)更緊湊。
總結(jié)
Lambda 引入,使我們在某些情況下,能夠?qū)㈩愃朴诤瘮?shù)的表達式用作接受函數(shù)指針或函數(shù)符的函數(shù)的參數(shù)。它更像膠水代碼,允許我們將簡單的處理邏輯傳遞到需要的位置,提高開發(fā)效率,使得代碼結(jié)構(gòu)簡潔而且易于理解。
-
C++語言
+關注
關注
0文章
147瀏覽量
6951 -
STL算法
+關注
關注
0文章
6瀏覽量
5358 -
gcc編譯器
+關注
關注
0文章
78瀏覽量
3346 -
Lambda
+關注
關注
0文章
28瀏覽量
9848
發(fā)布評論請先 登錄
相關推薦
評論