欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

C++11中匿名函數(shù)lambda的使用詳解

 更新時間:2023年04月27日 10:53:41   作者:Thomas_Lbw  
我最早接觸lambda的概念是在matlab中,那時候在做數(shù)值模擬的課題,lambda可以快速定義簡單的函數(shù),當(dāng)時覺得好方便。任何語言都有這個功能,下面來看看C++11新引入的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)文章

最新評論