C++11中匿名函數(shù)lambda的使用詳解
官方介紹:
C++ lambda是C++11新增的一種匿名函數(shù)的實(shí)現(xiàn)方式,可以在代碼中直接定義一個(gè)函數(shù)對(duì)象。它的語法是通過關(guān)鍵字“[]”來定義的,括號(hào)里可以包含需要訪問的外部變量。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),用于指定返回值類型。如果省略,編譯器會(huì)自動(dòng)推斷。
- function body: 函數(shù)主體。
通常情況下,一個(gè) 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í)候,用于表示參數(shù)列表的括號(hào)也是可以省略的:
[captures] {body}
//也就是
[]{}
具體的例子:
[](){} //定義一個(gè)沒有參數(shù)和返回值的lambda表達(dá)式
[](int a, int b){ return a+b;} //定義一個(gè)帶有參數(shù)的lambda表達(dá)式
[x](int a){ return x*a;} //定義一個(gè)捕獲x的lambda表達(dá)式
Lambda表達(dá)式還可以使用默認(rèn)參數(shù)值,通過在參數(shù)后面使用 "= default_value"來實(shí)現(xiàn)。
例如 :
[](int a, int b = 10){ return a + b;} //定義一個(gè)帶有默認(rèn)參數(shù)值的lambda表達(dá)式在捕獲列表中, 你可以使用&或=來捕獲外部變量。
- & 使得lambda表達(dá)式可以修改捕獲的變量。
- = 使得lambda表達(dá)式不能修改捕獲的變量(默認(rèn)值)。
例如 :
int x = 10;
[&x](){x++;} //定義一個(gè)可以修改x的lambda表達(dá)式
[=x](){x++;} //定義一個(gè)不能修改x的lambda表達(dá)式Lambda表達(dá)式可以通過賦值給std::function對(duì)象或者直接調(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等需要一個(gè)可調(diào)用的對(duì)象來完成操作,這時(shí)候lambda表達(dá)式可以提供一種簡潔的方式來定義這個(gè)可調(diào)用的對(duì)象。
#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第三個(gè)參數(shù)可以傳入一個(gè)函數(shù),是因?yàn)?sort 使用了模板,第三個(gè)參數(shù)是一個(gè)比較函數(shù),它是一個(gè)可以接受兩個(gè)參數(shù)并返回一個(gè)bool值的函數(shù)。sort函數(shù)使用這個(gè)比較函數(shù)來確定如何排序序列中的元素。如果第三個(gè)參數(shù)省略,sort默認(rèn)使用“小于”運(yùn)算符進(jìn)行比較。
可以使用 std::less<int> 替換 lambda 表達(dá)式,如下所示:
std::sort(v.begin(), v.end(), std::less<int>());
或者你也可以定義一個(gè)比較函數(shù)來代替 lambda:
bool myCompare(int a, int b)
{ return a < b; }
std::sort(v.begin(), v.end(), myCompare);
2.2 回調(diào)函數(shù)
在許多情況下,我們需要在某個(gè)對(duì)象的回調(diào)函數(shù)中進(jìn)行某些操作,這時(shí)候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ù)接收一個(gè) std::function<void()> 類型的參數(shù),并將其存儲(chǔ)在類的私有成員變量 "m_onClick" 中。std::function 是一種 C++11 標(biāo)準(zhǔn)庫中的類型,它可以存儲(chǔ)可調(diào)用的對(duì)象,如函數(shù)指針、函數(shù)對(duì)象、Lambda 表達(dá)式等,這段代碼它存了一個(gè)void()的類型的調(diào)用。
"click" 函數(shù)調(diào)用了 "m_onClick",也就是之前設(shè)置的 std::function<void()> 類型的回調(diào)函數(shù)。
在 main 函數(shù)中,一個(gè) Button 對(duì)象 "btn" 被創(chuàng)建并初始化。 然后調(diào)用 btn.setOnClick({std::cout << "Button clicked" << std::endl;}); 這個(gè)方法,將一個(gè) lambda 表達(dá)式作為參數(shù)設(shè)置給 m_onClick。 最后調(diào)用 btn.click(); 觸發(fā)了上面設(shè)置的 lambda 表達(dá)式。
2.3 多線程編程
在多線程編程中,我們需要啟動(dòng)一個(gè)新線程來執(zhí)行某些操作,這時(shí)候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ù)中,一個(gè) int 類型的變量 x 被賦值為 10。然后創(chuàng)建了一個(gè) std::thread 對(duì)象 "t",該對(duì)象的構(gòu)造函數(shù)接收了一個(gè) lambda 表達(dá)式,在這個(gè) lambda 表達(dá)式中,變量 x 的值被自增。
三、總結(jié)
在使用lambda時(shí)首先要明確它和普通函數(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)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C語言實(shí)現(xiàn)電話訂餐管理系統(tǒng)
這篇文章主要為大家詳細(xì)介紹了C語言實(shí)現(xiàn)電話訂餐管理系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-01-01
C++ 通過指針實(shí)現(xiàn)多態(tài)實(shí)例詳解
這篇文章主要介紹了 C++ 通過指針實(shí)現(xiàn)多態(tài)實(shí)例詳解的相關(guān)資料,需要的朋友可以參考下2017-03-03
C++實(shí)操之內(nèi)聯(lián)成員函數(shù)介紹
大家好,本篇文章主要講的是C++實(shí)操之內(nèi)聯(lián)成員函數(shù)介紹,感興趣的同學(xué)趕快來看一看吧,對(duì)你有幫助的話記得收藏一下,方便下次瀏覽2021-12-12

