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

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

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

lambda

lambda表達(dá)式語(yǔ)法

  • lambda 表達(dá)式本質(zhì)是一個(gè)匿名函數(shù)對(duì)象,可以定義在函數(shù)內(nèi)部,一般用auto或者模板參數(shù)定義的對(duì)象去接收 lambda 對(duì)象
  • 格式:[捕捉列表] (參數(shù)列表) -> 返回值類型 {函數(shù)體}
    • [捕捉列表] :根據(jù)[]來(lái)判斷接下來(lái)的代碼是不是lambda函數(shù),捕捉列表為空也不能省略
    • (參數(shù)列表):如果不需要參數(shù)傳遞,則可以連同()一起省略
    • -> 返回值類型:沒(méi)有返回值和返回值類型明確的情況下,也可以省略,由編譯器對(duì)返回類型進(jìn)行推導(dǎo)
    • {函數(shù)體}:在函數(shù)體內(nèi),除了可以使用其參數(shù)外,還可以使用所有捕獲到的變量,函數(shù)體為空也不能省略
  • lambda表達(dá)式適用于輕量級(jí)的局部小函數(shù),不能遞歸調(diào)用
int main()
{
    //一個(gè)簡(jiǎn)單的lambda表達(dá)式
    auto add1 = [](int x, int y)->int
        {
            return x + y;
        };
    cout << add1(1, 2) << endl; //3
    //1.捕捉為空也不能省略
    //2.參數(shù)為空可以省略
    //3.返回值可以省略,可以通過(guò)返回對(duì)象自動(dòng)推導(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)行捕捉
  • 第一種捕捉方式:在捕捉列表中顯示的傳值捕捉或傳引用捕捉,捕捉的多個(gè)變量用逗號(hào)分割。[x,y,&z]表示x和y值捕捉,z引用捕捉
  • 第二種捕捉方式:在捕捉列表中隱式捕捉。在捕捉列表寫(xiě)一個(gè)=表示隱式值捕捉,在捕捉列表寫(xiě)一個(gè)&表示隱式引用捕捉,這樣寫(xiě)的話lambda表達(dá)式中用了哪些變量,編譯器就會(huì)自動(dòng)捕捉哪些變量,不會(huì)全部捕捉
  • 第三種捕捉方式:混合使用隱式捕捉和顯示捕捉
    • [=,&x]表示其他變量隱式值捕捉,x引用捕捉
    • [&,x,y]表示其他變量引用步驟,x和y值捕捉
  • lambda表達(dá)式如果在函數(shù)局部域中,捕捉列表可以捕捉lambda位置之前的變量(除了類域,其余都是向上查找),不能捕捉靜態(tài)變量和全局變量,靜態(tài)變量和全局變量也不需要捕捉,在lambda表達(dá)式中可以直接使用。這也就意味者,lambda表達(dá)式如果定義在全局位置,捕捉列表必須為空(一般也不會(huì)寫(xiě)到全局)
  • 默認(rèn)情況下,lambda捕捉列表是被const修飾的,也就是說(shuō)傳值捕捉過(guò)來(lái)的對(duì)象不能修改。mutable加到參數(shù)列表的后面可以取消其常量屬性。也就是說(shuō),使用mutable修飾符后,傳值捕捉的對(duì)象就可以修改了,但是修改的還是形參對(duì)象,不會(huì)影響實(shí)參。使用該修飾符后,參數(shù)列表不可省略(即使參數(shù)為空)
int x = 0;
//定義在全局捕捉列表必須為空,因?yàn)槿肿兞坎挥貌蹲骄涂梢杂?,沒(méi)有可捕捉的變量
auto func1 = []()
    {
        x++;
    };
int main()
{
    //只能用當(dāng)前l(fā)ambda局部域和捕捉的對(duì)象和全局對(duì)象
    int a = 0, b = 1, c = 2, d = 3;
    auto func1 = [a, &b]    //除了類域,都是向上查找
        {
            //值捕捉的變量不能修改,引用捕捉的變量可以修改
            //a++ //錯(cuò)誤
            b++; //會(huì)影響外面的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屬性,可以修改了
    //但是修改不會(huì)影響外面被捕捉的值,因?yàn)槭且环N拷貝
    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;  //價(jià)格
    int _evaluate;  //評(píng)價(jià)
    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 = { { "蘋(píng)果", 2.1, 5 }, { "?蕉", 3, 4 }, 
    { "橙?", 2.2, 3 }, { "菠蘿", 1.5, 4 } };
    //類似這樣的場(chǎng)景,我們實(shí)現(xiàn)仿函數(shù)對(duì)象或者函數(shù)指針支持不同項(xiàng)的比較
    //相對(duì)還是比較麻煩的,不寫(xiě)注釋也方便理解,那么用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ù)對(duì)象,也就是說(shuō)我們寫(xiě)了一個(gè)lambda之后,編譯器會(huì)生成一個(gè)對(duì)應(yīng)的仿函數(shù)的類
  • lambda參數(shù)/返回類型/函數(shù)體就是仿函數(shù)operator()的參數(shù)/返回類型/函數(shù)體,lambda的捕捉列表本質(zhì)是生成的仿函數(shù)類的成員變量,也就是說(shuō)捕捉列表的變量都是lambda類構(gòu)造函數(shù)的實(shí)參

包裝器

  • 要==#include <functional>==

function

  • std::function 是一個(gè)類模板,也是一個(gè)包裝器。std::function 的實(shí)例對(duì)象可以包裝存儲(chǔ)其他的可調(diào)用對(duì)象,包括函數(shù)指針、仿函數(shù)、lambda、blind表達(dá)式等,存儲(chǔ)的可調(diào)用對(duì)象成為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)用對(duì)象的類型不同,std::function的優(yōu)勢(shì)就是同一類型,對(duì)他們進(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)用對(duì)象,需要參數(shù)類型匹配
    function<int(int, int)> f1 = f; //第一個(gè)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ù)還有一個(gè)隱含的this指針參數(shù),
    //所以綁定時(shí)要傳對(duì)象或者對(duì)象的引用或指針過(guò)去
    function<double(Plus*, double, double)> f5 = &Plus::plusd;
    Plus pd;    //是用傳入的對(duì)象去調(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;   //用匿名對(duì)象
    return 0;
}

bind

  • bind 是一個(gè)函數(shù)模板,他也是一個(gè)可調(diào)用對(duì)象的包裝器,對(duì)接受的fn可調(diào)用對(duì)象進(jìn)行處理后返回一個(gè)可調(diào)用對(duì)象。
  • bind可以用來(lái)調(diào)整參數(shù)個(gè)數(shù)和參數(shù)順序,它也包含在<functional>頭文件中
  • 格式:auto newCallable = bind(callable,arg_list);
    • newCallable本身是一個(gè)可調(diào)用對(duì)象
    • arg_list是一個(gè)逗號(hào)分割的參數(shù)列表,對(duì)應(yīng)給定的callable的參數(shù)
    • 當(dāng)我們調(diào)用newCallable時(shí),newCallable會(huì)調(diào)用callable,并傳給它arg_list中的參數(shù)
  • arg_list中的參數(shù)可能包含形如_n的名字,其中n是一個(gè)整數(shù),這些參數(shù)是占位符,表示newCallable的參數(shù),他們占據(jù)了傳遞給newCallable的參數(shù)的位置。數(shù)值n表示生成的可調(diào)用對(duì)象中參數(shù)的位置:_1為newCallable的第一個(gè)參數(shù),_2為第二個(gè)參數(shù),以此類推。_1/_2/_3…這些占位符放到placeholders的一個(gè)命名空間
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ì)是返回的一個(gè)仿函數(shù)對(duì)象
    //調(diào)整參數(shù)順序(不常用)
    //_1表示第一個(gè)實(shí)參
    //_2表示第二個(gè)實(shí)參
    //……
    auto sub2 = bind(Sub, _2, _1);
    cout << sub2(10, 5) << endl;    //-50
    //調(diào)整參數(shù)個(gè)數(shù)(常用)
    auto sub3 = bind(Sub, 100, _1); //把a(bǔ)固定為100
    cout << sub3(3) << endl;    //970
    auto sub4 = bind(Sub, _1, 100); //把b固定為100
    cout << sub4(3) << endl;    //-970
    //分別綁死第123個(gè)參數(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ù)對(duì)象進(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)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

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

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

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

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

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

    C語(yǔ)言實(shí)現(xiàn)詞法分析器

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

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

    這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言學(xué)生成績(jī)管理系統(tǒng)課程設(shè)計(jì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    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ù)格式,能夠存儲(chǔ)多個(gè)同類型的值。每個(gè)值都存儲(chǔ)在一個(gè)獨(dú)立的數(shù)組元素中,計(jì)算機(jī)在內(nèi)存中依次存儲(chǔ)數(shù)組的各個(gè)元素,今天給大家重點(diǎn)介紹C++ Primer Plus復(fù)合類型的實(shí)例詳解,感興趣的朋友一起看看吧
    2021-07-07
  • C++ socket實(shí)現(xiàn)miniFTP

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

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

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

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

    C++繼承介紹

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

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

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

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

    下面小編就為大家?guī)?lái)一篇深入理解c++指針的指針和指針的引用。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考,一起跟隨小編過(guò)來(lái)看看吧
    2016-06-06

最新評(píng)論

藁城市| 泰来县| 榆林市| 洛扎县| 都兰县| 民勤县| 滦南县| 东台市| 通许县| 拉萨市| 元谋县| 卓尼县| 綦江县| 周宁县| 靖边县| 上犹县| 孝义市| 桃园市| 镇坪县| 静安区| 滨海县| 城固县| 松江区| 南充市| 徐州市| 峨山| 航空| 丘北县| 崇明县| 蓬莱市| 手游| 贵州省| 青州市| 丹棱县| 新郑市| 宜良县| 五常市| 丰城市| 沙坪坝区| 青浦区| 宿州市|