您好,登錄后才能下訂單哦!
這篇文章主要介紹“C++11中的匿名函數lambda怎么使用”,在日常操作中,相信很多人在C++11中的匿名函數lambda怎么使用問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”C++11中的匿名函數lambda怎么使用”的疑惑有所幫助!接下來,請跟著小編一起來學習吧!
官方介紹:
C++ lambda是C++11新增的一種匿名函數的實現方式,可以在代碼中直接定義一個函數對象。它的語法是通過關鍵字“[]”來定義的,括號里可以包含需要訪問的外部變量。Lambda函數可以用于在STL算法中提供自定義的比較函數,或者作為std::function的參數。它的簡潔和易用性使得在C++11中變得非常流行。
Lambda表達式的完整聲明格式如下:
[capture list](parameter list) mutable exception-> return type { function body }
capture list: 用于捕獲外部變量的列表,可以省略。
parameter list: 函數參數列表,可以省略。
mutable: 可選項,用于指定能否修改捕獲的變量。
exception: 可選項,用于指定能拋出的異常。
return type: 可選項,用于指定返回值類型。如果省略,編譯器會自動推斷。
function body: 函數主體。
通常情況下,一個 lambda 表達式不需要如此多的關鍵詞,更常用的聲明形式如下,只需要captures、parameters、return type、body即可:
[captures] (parameters) -> return_type {body}
有一些情況下,返回類型可以從 return 語句中推導(如 auto),則返回類型可以省略。而當 lambda 表達式沒有參數的時候,用于表示參數列表的括號也是可以省略的:
[captures] {body} //也就是 []{}
具體的例子:
[](){} //定義一個沒有參數和返回值的lambda表達式 [](int a, int b){ return a+b;} //定義一個帶有參數的lambda表達式 [x](int a){ return x*a;} //定義一個捕獲x的lambda表達式
Lambda表達式還可以使用默認參數值,通過在參數后面使用 "= default_value"來實現。
例如 :
[](int a, int b = 10){ return a + b;} //定義一個帶有默認參數值的lambda表達式
在捕獲列表中, 你可以使用&或=來捕獲外部變量。
& 使得lambda表達式可以修改捕獲的變量。
= 使得lambda表達式不能修改捕獲的變量(默認值)。
例如 :
int x = 10; [&x](){x++;} //定義一個可以修改x的lambda表達式 [=x](){x++;} //定義一個不能修改x的lambda表達式
Lambda表達式可以通過賦值給std::function對象或者直接調用來使用。
例如 :
std::function<int(int, int)> add = [](int a, int b){ return a + b;}; int result = add(1, 2);
STL算法如sort, for_each等需要一個可調用的對象來完成操作,這時候lambda表達式可以提供一種簡潔的方式來定義這個可調用的對象。
#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第三個參數可以傳入一個函數,是因為 sort 使用了模板,第三個參數是一個比較函數,它是一個可以接受兩個參數并返回一個bool值的函數。sort函數使用這個比較函數來確定如何排序序列中的元素。如果第三個參數省略,sort默認使用“小于”運算符進行比較。
可以使用 std::less<int> 替換 lambda 表達式,如下所示:
std::sort(v.begin(), v.end(), std::less<int>());
或者你也可以定義一個比較函數來代替 lambda:
bool myCompare(int a, int b) { return a < b; } std::sort(v.begin(), v.end(), myCompare);
在許多情況下,我們需要在某個對象的回調函數中進行某些操作,這時候lambda表達式可以提供一種簡潔的方式來定義回調函數。
#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" 函數接收一個 std::function<void()> 類型的參數,并將其存儲在類的私有成員變量 "m_onClick" 中。std::function 是一種 C++11 標準庫中的類型,它可以存儲可調用的對象,如函數指針、函數對象、Lambda 表達式等,這段代碼它存了一個void()的類型的調用。
"click" 函數調用了 "m_onClick",也就是之前設置的 std::function<void()> 類型的回調函數。
在 main 函數中,一個 Button 對象 "btn" 被創建并初始化。 然后調用 btn.setOnClick({std::cout << "Button clicked" << std::endl;}); 這個方法,將一個 lambda 表達式作為參數設置給 m_onClick。 最后調用 btn.click(); 觸發了上面設置的 lambda 表達式。
在多線程編程中,我們需要啟動一個新線程來執行某些操作,這時候lambda表達式可以提供一種簡潔的方式來定義線程的操作。
#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 函數中,一個 int 類型的變量 x 被賦值為 10。然后創建了一個 std::thread 對象 "t",該對象的構造函數接收了一個 lambda 表達式,在這個 lambda 表達式中,變量 x 的值被自增。
到此,關于“C++11中的匿名函數lambda怎么使用”的學習就結束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續學習更多相關知識,請繼續關注億速云網站,小編會繼續努力為大家帶來更多實用的文章!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。