為什么引入Lambda
Lambda表達式是一個可以內聯在我們代碼中的函數,我們可以將他傳遞給另外一個函數。在沒有引入Lambda表達式之前,當我們遇到需要對多個數據,按照同一規(guī)則進行操作的時候,創(chuàng)建機動函數會更簡單,但是必須在其他地方定義好該函數,然后再使用它,有時候兩者之間可能距離離的很遠,想要了解該函數內部操作的原理,需要翻閱多頁源代碼找它的定義,這樣使得代碼的可讀性大打折扣。這就是Lambda表達式出現的主要原因。
基本的Lambda語法
lambda表達式是一個匿名函數。其可以捕獲作用域中的變量。其在C++11中常用的語法如下:
[captures](params){body}
[captures]{body} //省略了形參列表,函數不接收實參,如同形參列表為()
[captures](params)- >return-type{body} //return-type為返回類型
//eg:
//捕獲列表 參數列表 函數體
[] (int a, int b) { return a < b;}
//捕獲列表 參數列表 返回類型 函數體
[] (double x) - > double {int y = x; return x - y;}
/*注:Lambda函數沒有聲明返回類型,其返回類型相當于使用decltyp根據返回值推斷得到的。
如果函數體內不包含返回語句,則推斷出返回類型為void。
但是僅當函數體完全由一條返回語句組成時,自動類型推斷才管用
否則,需要使用新增的返回類型后置語法*/
【 注 :Lambda表達式自動推斷返回值類型:有些編譯器,像GCC,即使你有多于一個返回語句也不可以自動推斷成功,但標準不保證這一點,因此為了防止意外的發(fā)生,當函數體內返回語句不止一條的時候,建議使用返回類型后置語法】
其中captures
為捕獲,它一個包含0個或者多個捕獲符的用逗號分隔的列表。params
為參數列表,body
為函數體。默認的捕獲符只有:
&
:采用引用隱式捕獲的方式使用自動變量=
:采用復制隱式捕獲的方式使用自動變量[] // 默認不捕獲 [&] // 默認以引用捕獲(意味著在函數體內可以按照引用的方式使用Lambda表達式所在范圍內所有可見的局部變量) [&, i] // 以引用捕獲(同上),但i以值捕獲 [=] // 默認以復制捕獲(意味著在函數體內可以按照值傳遞的方式使用Lambda表達式所在范圍內所有可見的局部變量) [=, &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;
}
程序輸出結果:
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的結合
當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表達式后,代碼顯的更漂亮,而且它的可讀性也很強,結構更緊湊。
總結
Lambda 引入,使我們在某些情況下,能夠將類似于函數的表達式用作接受函數指針或函數符的函數的參數。它更像膠水代碼,允許我們將簡單的處理邏輯傳遞到需要的位置,提高開發(fā)效率,使得代碼結構簡潔而且易于理解。
-
C++語言
+關注
關注
0文章
147瀏覽量
6989 -
STL算法
+關注
關注
0文章
6瀏覽量
5366 -
gcc編譯器
+關注
關注
0文章
78瀏覽量
3380 -
Lambda
+關注
關注
0文章
28瀏覽量
9872
發(fā)布評論請先 登錄
相關推薦
評論