C++11中匿名函數(shù)lambda的使用詳解
官方介紹:
C++ lambda是C++11新增的一種匿名函數(shù)的實(shí)現(xiàn)方式,可以在代碼中直接定義一個函數(shù)對象。它的語法是通過關(guān)鍵字“[]”來定義的,括號里可以包含需要訪問的外部變量。Lambda函數(shù)可以用于在STL算法中提供自定義的比較函數(shù),或者作為std::function的參數(shù)。它的簡潔和易用性使得在C++11中變得非常流行。
一、lambda基礎(chǔ)介紹
Lambda表達(dá)式的完整聲明格式如下:
[capture list](parameter list) mutable exception-> return type { function body }
- capture list: 用于捕獲外部變量的列表,可以省略。
- parameter list: 函數(shù)參數(shù)列表,可以省略。
- mutable: 可選項(xiàng),用于指定能否修改捕獲的變量。
- exception: 可選項(xiàng),用于指定能拋出的異常。
- return type: 可選項(xiàng),用于指定返回值類型。如果省略,編譯器會自動推斷。
- function body: 函數(shù)主體。
通常情況下,一個 lambda 表達(dá)式不需要如此多的關(guān)鍵詞,更常用的聲明形式如下,只需要captures、parameters、return type、body即可:
[captures] (parameters) -> return_type {body}
有一些情況下,返回類型可以從 return 語句中推導(dǎo)(如 auto),則返回類型可以省略。而當(dāng) lambda 表達(dá)式?jīng)]有參數(shù)的時候,用于表示參數(shù)列表的括號也是可以省略的:
[captures] {body} //也就是 []{}
具體的例子:
[](){} //定義一個沒有參數(shù)和返回值的lambda表達(dá)式 [](int a, int b){ return a+b;} //定義一個帶有參數(shù)的lambda表達(dá)式 [x](int a){ return x*a;} //定義一個捕獲x的lambda表達(dá)式
Lambda表達(dá)式還可以使用默認(rèn)參數(shù)值,通過在參數(shù)后面使用 "= default_value"來實(shí)現(xiàn)。
例如 :
[](int a, int b = 10){ return a + b;} //定義一個帶有默認(rèn)參數(shù)值的lambda表達(dá)式
在捕獲列表中, 你可以使用&或=來捕獲外部變量。
- & 使得lambda表達(dá)式可以修改捕獲的變量。
- = 使得lambda表達(dá)式不能修改捕獲的變量(默認(rèn)值)。
例如 :
int x = 10; [&x](){x++;} //定義一個可以修改x的lambda表達(dá)式 [=x](){x++;} //定義一個不能修改x的lambda表達(dá)式
Lambda表達(dá)式可以通過賦值給std::function對象或者直接調(diào)用來使用。
例如 :
std::function<int(int, int)> add = [](int a, int b){ return a + b;}; int result = add(1, 2);
二、lambda使用例子
2.1 STL算法中的回調(diào)函數(shù)
STL算法如sort, for_each等需要一個可調(diào)用的對象來完成操作,這時候lambda表達(dá)式可以提供一種簡潔的方式來定義這個可調(diào)用的對象。
#include <algorithm> #include <iostream> #include <vector> int main() { std::vector<int> v{3, 1, 4, 1, 5, 9, 2, 6, 5}; std::sort(v.begin(), v.end(), [](int a, int b){ return a < b;}); for(int x : v) std::cout << x << " "; std::cout << std::endl; return 0; }
sort第三個參數(shù)可以傳入一個函數(shù),是因?yàn)?sort 使用了模板,第三個參數(shù)是一個比較函數(shù),它是一個可以接受兩個參數(shù)并返回一個bool值的函數(shù)。sort函數(shù)使用這個比較函數(shù)來確定如何排序序列中的元素。如果第三個參數(shù)省略,sort默認(rèn)使用“小于”運(yùn)算符進(jìn)行比較。
可以使用 std::less<int> 替換 lambda 表達(dá)式,如下所示:
std::sort(v.begin(), v.end(), std::less<int>());
或者你也可以定義一個比較函數(shù)來代替 lambda:
bool myCompare(int a, int b) { return a < b; } std::sort(v.begin(), v.end(), myCompare);
2.2 回調(diào)函數(shù)
在許多情況下,我們需要在某個對象的回調(diào)函數(shù)中進(jìn)行某些操作,這時候lambda表達(dá)式可以提供一種簡潔的方式來定義回調(diào)函數(shù)。
#include <iostream> class Button { public: void setOnClick(std::function<void()> onClick) { m_onClick = onClick; } void click() { m_onClick(); } private: std::function<void()> m_onClick; }; int main() { Button btn; btn.setOnClick([](){std::cout << "Button clicked" << std::endl;}); btn.click(); return 0; }
"setOnClick" 函數(shù)接收一個 std::function<void()> 類型的參數(shù),并將其存儲在類的私有成員變量 "m_onClick" 中。std::function 是一種 C++11 標(biāo)準(zhǔn)庫中的類型,它可以存儲可調(diào)用的對象,如函數(shù)指針、函數(shù)對象、Lambda 表達(dá)式等,這段代碼它存了一個void()的類型的調(diào)用。
"click" 函數(shù)調(diào)用了 "m_onClick",也就是之前設(shè)置的 std::function<void()> 類型的回調(diào)函數(shù)。
在 main 函數(shù)中,一個 Button 對象 "btn" 被創(chuàng)建并初始化。 然后調(diào)用 btn.setOnClick({std::cout << "Button clicked" << std::endl;}); 這個方法,將一個 lambda 表達(dá)式作為參數(shù)設(shè)置給 m_onClick。 最后調(diào)用 btn.click(); 觸發(fā)了上面設(shè)置的 lambda 表達(dá)式。
2.3 多線程編程
在多線程編程中,我們需要啟動一個新線程來執(zhí)行某些操作,這時候lambda表達(dá)式可以提供一種簡潔的方式來定義線程的操作。
#include <iostream> #include <thread> int main() { int x = 10; std::thread t([&x](){ x++;}); t.join(); std::cout << x << std::endl; return 0; }
這段代碼使用了 C++11 的線程庫 std::thread。在 main 函數(shù)中,一個 int 類型的變量 x 被賦值為 10。然后創(chuàng)建了一個 std::thread 對象 "t",該對象的構(gòu)造函數(shù)接收了一個 lambda 表達(dá)式,在這個 lambda 表達(dá)式中,變量 x 的值被自增。
三、總結(jié)
在使用lambda時首先要明確它和普通函數(shù)一樣,有函數(shù)地址、參數(shù)、返回值等等,使用起來不要有任何負(fù)擔(dān)。第二就是掌握它復(fù)雜的使用方法需要多多使用,多多練習(xí),C++新特性的學(xué)習(xí)有助于我們掌握更好的編程技巧。
到此這篇關(guān)于C++11中匿名函數(shù)lambda的使用詳解的文章就介紹到這了,更多相關(guān)C++11匿名函數(shù)lambda內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
c++ 結(jié)構(gòu)體內(nèi)存對齊基本概念及示例
這篇文章主要介紹了c++ 結(jié)構(gòu)體內(nèi)存對齊基本概念及示例,幫助大家更好的理解和學(xué)習(xí)c++,感興趣的朋友可以了解下2020-12-12C/C++靜態(tài)類和this指針詳解及實(shí)例代碼
這篇文章主要介紹了 C/C++靜態(tài)類和this指針詳解及實(shí)例代碼的相關(guān)資料,需要的朋友可以參考下2017-02-02