最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C++11新特性之lambda、包裝器詳解

 更新時間:2026年02月25日 09:28:37   作者:霧島聽藍(lán)  
lambda表達(dá)式是一種匿名函數(shù)對象,可以定義在函數(shù)內(nèi)部,用于定義輕量級的局部小函數(shù),本文給大家介紹C++11新特性之lambda、包裝器的相關(guān)知識,感興趣的朋友跟隨小編一起看看吧

lambda

lambda表達(dá)式語法

  • lambda 表達(dá)式本質(zhì)是一個匿名函數(shù)對象,可以定義在函數(shù)內(nèi)部,一般用auto或者模板參數(shù)定義的對象去接收 lambda 對象
  • 格式:[捕捉列表] (參數(shù)列表) -> 返回值類型 {函數(shù)體}
    • [捕捉列表] :根據(jù)[]來判斷接下來的代碼是不是lambda函數(shù),捕捉列表為空也不能省略
    • (參數(shù)列表):如果不需要參數(shù)傳遞,則可以連同()一起省略
    • -> 返回值類型:沒有返回值和返回值類型明確的情況下,也可以省略,由編譯器對返回類型進(jìn)行推導(dǎo)
    • {函數(shù)體}:在函數(shù)體內(nèi),除了可以使用其參數(shù)外,還可以使用所有捕獲到的變量,函數(shù)體為空也不能省略
  • lambda表達(dá)式適用于輕量級的局部小函數(shù),不能遞歸調(diào)用
int main()
{
    //一個簡單的lambda表達(dá)式
    auto add1 = [](int x, int y)->int
        {
            return x + y;
        };
    cout << add1(1, 2) << endl; //3
    //1.捕捉為空也不能省略
    //2.參數(shù)為空可以省略
    //3.返回值可以省略,可以通過返回對象自動推導(dǎo)
    //4.函數(shù)體不能省略
    auto func1 = []  //省略參數(shù)、返回類型
        {
            cout << "hello ssp" << endl;
            return 0;
        };
    func1();    //hello ssp
    int a = 0, b = 1;
    auto swap1 = [](int& x, int& y)  //省略返回類型
        {
            int tmp = x;
            x = y;
            y = tmp;
        };
    swap1(a, b);
    cout << a << ":" << b << endl;  //1:0
    return 0;
}

捕捉列表

  • lambda默認(rèn)只能用lambda函數(shù)體和參數(shù)中的變量,如果想用外層作用域中的變量就需要進(jìn)行捕捉
  • 第一種捕捉方式:在捕捉列表中顯示的傳值捕捉或傳引用捕捉,捕捉的多個變量用逗號分割。[x,y,&z]表示x和y值捕捉,z引用捕捉
  • 第二種捕捉方式:在捕捉列表中隱式捕捉。在捕捉列表寫一個=表示隱式值捕捉,在捕捉列表寫一個&表示隱式引用捕捉,這樣寫的話lambda表達(dá)式中用了哪些變量,編譯器就會自動捕捉哪些變量,不會全部捕捉
  • 第三種捕捉方式:混合使用隱式捕捉和顯示捕捉
    • [=,&x]表示其他變量隱式值捕捉,x引用捕捉
    • [&,x,y]表示其他變量引用步驟,x和y值捕捉
  • lambda表達(dá)式如果在函數(shù)局部域中,捕捉列表可以捕捉lambda位置之前的變量(除了類域,其余都是向上查找),不能捕捉靜態(tài)變量和全局變量,靜態(tài)變量和全局變量也不需要捕捉,在lambda表達(dá)式中可以直接使用。這也就意味者,lambda表達(dá)式如果定義在全局位置,捕捉列表必須為空(一般也不會寫到全局)
  • 默認(rèn)情況下,lambda捕捉列表是被const修飾的,也就是說傳值捕捉過來的對象不能修改。mutable加到參數(shù)列表的后面可以取消其常量屬性。也就是說,使用mutable修飾符后,傳值捕捉的對象就可以修改了,但是修改的還是形參對象,不會影響實參。使用該修飾符后,參數(shù)列表不可省略(即使參數(shù)為空)
int x = 0;
//定義在全局捕捉列表必須為空,因為全局變量不用捕捉就可以用,沒有可捕捉的變量
auto func1 = []()
    {
        x++;
    };
int main()
{
    //只能用當(dāng)前l(fā)ambda局部域和捕捉的對象和全局對象
    int a = 0, b = 1, c = 2, d = 3;
    auto func1 = [a, &b]    //除了類域,都是向上查找
        {
            //值捕捉的變量不能修改,引用捕捉的變量可以修改
            //a++ //錯誤
            b++; //會影響外面的b
            int ret = a + b;
            return ret;
        };
    cout << func1() << endl;    //2
    //隱式值捕捉
    //用了哪些變量就捕捉哪些變量
    auto func2 = [=]()
        {
            int ret = a + b + c;
            return ret;
        };
    cout << func2() << endl;    //4
    //隱式引用捕捉
    //用了哪些變量就捕捉哪些變量
    auto func3 = [&]
        {
            a++;
            c++;
            d++;
        };
    func3();
    cout << a << " " << b << " " << c << " " << d << endl;
    //1 2 3 4
    //混合捕捉1
    auto func4 = [&, a, b]
        {
            //a++;
            //b++;
            c++;
            d++;
            return a + b + c + d;
        };
    func4();
    cout << a << " " << b << " " << c << " " << d << endl;
    //1 2 4 5
    //混合捕捉2
    auto func5 = [=, &a, &b]
        {
            a++;
            b++;
            //c++;
            //d++;
            return a + b + c + d;
        };
    func5();
    cout << a << " " << b << " " << c << " " << d << endl;
    //2 3 4 5
    //局部的靜態(tài)和全局變量不能捕捉,也不需要捕捉
    static int m = 0;
    auto func6 = []
        {
            int ret = x + m;
            return ret;
        };
    //傳值捕捉本質(zhì)是一種拷貝,并且被const修飾了
    //mutable相當(dāng)于去掉const屬性,可以修改了
    //但是修改不會影響外面被捕捉的值,因為是一種拷貝
    auto func7 = [=]()mutable
        {
            a++;
            b++;
            c++;
            d++;
            return a + b + c + d;
        };
    cout << func7() << endl;    //18
    cout << a << " " << b << " " << c << " " << d << endl;
    //3 4 5 6
    return 0;
}

lambda應(yīng)用

struct Goods
{
    string _name;   //名字
    double _price;  //價格
    int _evaluate;  //評價
    Goods(const char* str, double price, int evaluate)
        :_name(str)
        , _price(price)
        , _evaluate(evaluate)
    {}
};
struct ComparePriceLess
{
    bool operator()(const Goods& gl, const Goods& gr)
    {
        return gl._price < gr._price;
    }
};
struct ComparePriceGreater
{
    bool operator()(const Goods& gl, const Goods& gr)
    {
        return gl._price > gr._price;
    }
};
int main()
{
    vector<Goods> v = { { "蘋果", 2.1, 5 }, { "?蕉", 3, 4 }, 
    { "橙?", 2.2, 3 }, { "菠蘿", 1.5, 4 } };
    //類似這樣的場景,我們實現(xiàn)仿函數(shù)對象或者函數(shù)指針支持不同項的比較
    //相對還是比較麻煩的,不寫注釋也方便理解,那么用lambda就很好用了
    sort(v.begin(), v.end(), ComparePriceLess());
    sort(v.begin(), v.end(), ComparePriceGreater());
    sort(v.begin(), v.end(), [](const Goods& g1, const Goods& g2) {
        return g1._price < g2._price; 
        });
    sort(v.begin(), v.end(), [](const Goods& g1, const Goods& g2) {
        return g1._price > g2._price;
        });
    sort(v.begin(), v.end(), [](const Goods& g1, const Goods& g2) {
        return g1._evaluate < g2._evaluate;
        });
    sort(v.begin(), v.end(), [](const Goods& g1, const Goods& g2) {
        return g1._evaluate > g2._evaluate;
        });
    return 0;
}

lambda的原理

  • lambda底層是仿函數(shù)對象,也就是說我們寫了一個lambda之后,編譯器會生成一個對應(yīng)的仿函數(shù)的類
  • lambda參數(shù)/返回類型/函數(shù)體就是仿函數(shù)operator()的參數(shù)/返回類型/函數(shù)體,lambda的捕捉列表本質(zhì)是生成的仿函數(shù)類的成員變量,也就是說捕捉列表的變量都是lambda類構(gòu)造函數(shù)的實參

包裝器

  • 要==#include <functional>==

function

  • std::function 是一個類模板,也是一個包裝器。std::function 的實例對象可以包裝存儲其他的可調(diào)用對象,包括函數(shù)指針、仿函數(shù)、lambda、blind表達(dá)式等,存儲的可調(diào)用對象成為std::function的目標(biāo)。若 std::function 不含目標(biāo),則稱它為空。調(diào)用空 std::function 的目標(biāo)導(dǎo)致拋出 std::bad_function_call 異常
  • 函數(shù)指針、仿函數(shù)、lambda等可調(diào)用對象的類型不同,std::function的優(yōu)勢就是同一類型,對他們進(jìn)行包裝。
#include <functional>
int f(int a, int b)
{
    return a + b;
}
struct Functor
{
public:
    int operator()(int a, int b)
    {
        return a + b;
    }
};
class Plus
{
public: 
    Plus(int n=10)
        :_n(n)
    { }
    static int plusi(int a, int b)
    {
        return a + b;
    }
    double plusd(double a, double b)
    {
        return (a + b) * _n;
    }
private:
    int _n;
};
int main()
{
    //包裝各種可調(diào)用對象,需要參數(shù)類型匹配
    function<int(int, int)> f1 = f; //第一個int是返回值類型,(int.int)為參數(shù)列表
    function<int(int, int)> f2 = Functor();
    function<int(int, int)> f3 = [](int a, int b) {return a + b; };
    cout << f1(1, 1) << endl;
    cout << f2(1, 1) << endl;
    cout << f3(1, 1) << endl;
    //包裝靜態(tài)成員函數(shù)
    //成員函數(shù)要指定類域并且前面加&才能獲取地址
    //&靜態(tài)的可加可不加,非靜態(tài)的必須加&
    function<int(int, int)> f4 = &Plus::plusi;
    cout << f4(1, 1) << endl;
    //包裝普通成員函數(shù)
    //普通成員函數(shù)還有一個隱含的this指針參數(shù),
    //所以綁定時要傳對象或者對象的引用或指針過去
    function<double(Plus*, double, double)> f5 = &Plus::plusd;
    Plus pd;    //是用傳入的對象去調(diào)用函數(shù)
    cout << f5(&pd, 1.1, 1.1) << endl;
    function<double(Plus, double, double)> f6 = &Plus::plusd;
    cout << f6(pd, 1.1, 1.1) << endl;
    function<double(Plus&&, double, double)> f7 = &Plus::plusd;
    cout << f7(move(pd), 1.1, 1.1) << endl; //用右值引用
    cout << f7(Plus(), 1.1, 1.1) << endl;   //用匿名對象
    return 0;
}

bind

  • bind 是一個函數(shù)模板,他也是一個可調(diào)用對象的包裝器,對接受的fn可調(diào)用對象進(jìn)行處理后返回一個可調(diào)用對象。
  • bind可以用來調(diào)整參數(shù)個數(shù)和參數(shù)順序,它也包含在<functional>頭文件中
  • 格式:auto newCallable = bind(callable,arg_list);
    • newCallable本身是一個可調(diào)用對象
    • arg_list是一個逗號分割的參數(shù)列表,對應(yīng)給定的callable的參數(shù)
    • 當(dāng)我們調(diào)用newCallable時,newCallable會調(diào)用callable,并傳給它arg_list中的參數(shù)
  • arg_list中的參數(shù)可能包含形如_n的名字,其中n是一個整數(shù),這些參數(shù)是占位符,表示newCallable的參數(shù),他們占據(jù)了傳遞給newCallable的參數(shù)的位置。數(shù)值n表示生成的可調(diào)用對象中參數(shù)的位置:_1為newCallable的第一個參數(shù),_2為第二個參數(shù),以此類推。_1/_2/_3…這些占位符放到placeholders的一個命名空間
class Plus
{
public: 
    Plus(int n=10)
        :_n(n)
    { }
    static int plusi(int a, int b)
    {
        return a + b;
    }
    double plusd(double a, double b)
    {
        return (a + b) * _n;
    }
private:
    int _n;
};
int main()
{
    auto sub1 = bind(Sub, _1, _2);
    cout << sub1(10, 5) << endl;    //50
    //bind本質(zhì)是返回的一個仿函數(shù)對象
    //調(diào)整參數(shù)順序(不常用)
    //_1表示第一個實參
    //_2表示第二個實參
    //……
    auto sub2 = bind(Sub, _2, _1);
    cout << sub2(10, 5) << endl;    //-50
    //調(diào)整參數(shù)個數(shù)(常用)
    auto sub3 = bind(Sub, 100, _1); //把a固定為100
    cout << sub3(3) << endl;    //970
    auto sub4 = bind(Sub, _1, 100); //把b固定為100
    cout << sub4(3) << endl;    //-970
    //分別綁死第123個參數(shù)
    auto sub5 = bind(SubX, 100, _1, _2);    //100-_1-_2
    cout << sub5(5, 1) << endl;
    auto sub6 = bind(SubX, _1, 100, _2);    //_1-100-_2
    cout << sub6(5, 1) << endl;
    auto sub7 = bind(SubX, _1, _2, 100);    //_1-_2-100
    cout << sub7(5, 1) << endl;
    //成員函數(shù)對象進(jìn)行綁死,就不需要每次傳遞了
    function<double(Plus&&, double, double)> f6 = &Plus::plusd;
    Plus pd;
    cout << f6(move(pd), 1.1, 1.1) << endl;
    cout << f6(Plus(), 1.1, 1.1) << endl;
    //bind一般用于綁死一些固定參數(shù)
    function<double(double, double)> f7 = bind(&Plus::plusd, Plus(), _1, _2);
    cout << f7(1.1, 1.1) << endl;
    return 0;
}

到此這篇關(guān)于C++11新特性之lambda、包裝器詳解的文章就介紹到這了,更多相關(guān)C++11 lambda 包裝器內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • C語言malloc與calloc區(qū)別詳解

    C語言malloc與calloc區(qū)別詳解

    本文主要介紹了C語言malloc與calloc區(qū)別詳解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-01-01
  • 詳解C/C++中的select、poll和epoll

    詳解C/C++中的select、poll和epoll

    本文通過示例介紹了C/C++中的select、poll和epoll知識,結(jié)合示例代碼給大家介紹的非常詳細(xì),需要的朋友參考下吧
    2023-06-06
  • C語言實現(xiàn)詞法分析器

    C語言實現(xiàn)詞法分析器

    這篇文章主要為大家詳細(xì)介紹了C語言實現(xiàn)詞法分析器,一個簡單的詞法分析程序,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-01-01
  • C語言學(xué)生成績管理系統(tǒng)課程設(shè)計

    C語言學(xué)生成績管理系統(tǒng)課程設(shè)計

    這篇文章主要為大家詳細(xì)介紹了C語言學(xué)生成績管理系統(tǒng)課程設(shè)計,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-01-01
  • C++ Primer Plus 第四章之C++ Primer Plus復(fù)合類型學(xué)習(xí)筆記

    C++ Primer Plus 第四章之C++ Primer Plus復(fù)合類型學(xué)習(xí)筆記

    數(shù)組(array)是一種數(shù)據(jù)格式,能夠存儲多個同類型的值。每個值都存儲在一個獨立的數(shù)組元素中,計算機在內(nèi)存中依次存儲數(shù)組的各個元素,今天給大家重點介紹C++ Primer Plus復(fù)合類型的實例詳解,感興趣的朋友一起看看吧
    2021-07-07
  • C++ socket實現(xiàn)miniFTP

    C++ socket實現(xiàn)miniFTP

    這篇文章主要為大家詳細(xì)介紹了C++ socket實現(xiàn)miniFTP的相關(guān)資料,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2016-11-11
  • 關(guān)于C語言一維數(shù)組算法問題詳解

    關(guān)于C語言一維數(shù)組算法問題詳解

    數(shù)組是以順序格式排列的均勻數(shù)據(jù)的集合,在C語言中學(xué)習(xí)數(shù)組的概念非常重要,因為它是基本的數(shù)據(jù)結(jié)構(gòu),這篇文章主要給大家介紹了關(guān)于C語言一維數(shù)組算法問題的相關(guān)資料,需要的朋友可以參考下
    2021-11-11
  • C++繼承介紹

    C++繼承介紹

    C++繼承可以是單一繼承或多重繼承,每一個繼承連接可以是public,protected,private也可以是virtual或non-virtual
    2013-01-01
  • C++實現(xiàn)單置換密碼

    C++實現(xiàn)單置換密碼

    這篇文章主要為大家詳細(xì)介紹了C++實現(xiàn)單置換密碼,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-03-03
  • 深入理解c++指針的指針和指針的引用

    深入理解c++指針的指針和指針的引用

    下面小編就為大家?guī)硪黄钊肜斫鈉++指針的指針和指針的引用。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考,一起跟隨小編過來看看吧
    2016-06-06

最新評論

江津市| 广宗县| 交城县| 绥宁县| 临西县| 绿春县| 巍山| 崇义县| 平罗县| 中卫市| 客服| 雷山县| 桃园县| 镇平县| 奉新县| 抚顺市| 泰州市| 田东县| 新兴县| 什邡市| 徐汇区| 萨迦县| 科技| 涡阳县| 博白县| 太仆寺旗| 崇明县| 商水县| 商南县| 额尔古纳市| 白河县| 会东县| 赤峰市| 织金县| 巴南区| 泗洪县| 万全县| 浑源县| 喀喇沁旗| 许昌县| 星子县|