日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

lambada表达式

發布時間:2024/9/27 编程问答 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 lambada表达式 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

  • lambda表達式

  • //C++ 11中的Lambda表達式用于定義并創建匿名的函數對象,以簡化編程工作。Lambda的語法形式如下:

    //[函數對象參數](操作符重載函數參數)mutableexception聲明->返回值類型{函數體 }

    ?

    //可以看到,Lambda主要分為五個部分:

    //[函數對象參數](操作符重載函數參數)mutableexception聲明、->返回值類型、{函數體 }。下面分別進行介紹。

    //一、[函數對象參數],標識一個Lambda的開始,這部分必須存在,不能省略。函數對象參數是傳遞給編譯器自動生成的函數對象類的構造函數的。

    //函數對象參數只能使用那些到定義Lambda為止時Lambda所在作用范圍內可見的局部變量(包括Lambda所在類的this)。函數對象參數有以下形式:

    //1、空。沒有使用任何函數對象參數。

    //2 =。函數體內可以使用Lambda所在作用范圍內所有可見的局部變量(包括Lambda所在類的this),并且是值傳遞方式(相當于編譯器自動為我們按值傳遞了所有局部變量)。

    //3&。函數體內可以使用Lambda所在作用范圍內所有可見的局部變量(包括Lambda所在類的this),并且是引用傳遞方式(相當于編譯器自動為我們按引用傳遞了所有局部變量)。

    //4this。函數體內可以使用Lambda所在類中的成員變量。

    //5a。將a按值進行傳遞。按值進行傳遞時,函數體內不能修改傳遞進來的a的拷貝,因為默認情況下函數是const的。要修改傳遞進來的a的拷貝,可以添加mutable修飾符。

    //6&a。將a按引用進行傳遞。

    //7a, &b。將a按值進行傳遞,b按引用進行傳遞。

    //8 =&a,&b。除ab按引用進行傳遞外,其他參數都按值進行傳遞。

    //9&, a, b。除ab按值進行傳遞外,其他參數都按引用進行傳遞。

    //二、(操作符重載函數參數),標識重載的()操作符的參數,沒有參數時,這部分可以省略。參數可以通過按值(如:(a, b))和按引用(如:(&a, &b))兩種方式進行傳遞。

    //三、mutableexception聲明,這部分可以省略。按值傳遞函數對象參數時,加上mutable修飾符后,可以修改按值傳遞進來的拷貝(注意是能修改拷貝,而不是值本身)。

    //exception聲明用于指定函數拋出的異常,如拋出整數類型的異常,可以使用throw(int)

    //四、->返回值類型,標識函數返回值的類型,當返回值為void,或者函數體中只有一處return的地方(此時編譯器可以自動推斷出返回值類型)時,這部分可以省略。

    //五、{函數體 },標識函數的實現,這部分不能省略,但函數體可以為空。

    案例1

    #include<functional>

    #include<iostream>

    #include<vector>

    #include<algorithm>

    ?

    usingnamespacestd;

    ?

    //lambda表達式簡單案例

    voidmain()

    {

    //[函數對象參數](操作符重載函數參數)mutableexception聲明、->返回值類型、{函數體 }

    ??????autofun1 = [](){cout <<"hellochina"<<endl; };

    ???fun1();

    ?

    ???autofun2 = [](inta,intb){returna +b; };

    ???cout <<fun2(10, 9) <<endl;

    ?

    ???std::cin.get();

    }

    運行結果:

    案例2

    #include<functional>

    #include<iostream>

    #include<vector>

    #include<algorithm>

    ?

    usingnamespacestd;

    ?

    voidmain()

    {

    ???vector<int>?myv;

    ???myv.push_back(1);

    ???myv.push_back(2);

    ???myv.push_back(11);

    ???autofun1 = [](intv){?cout <<v <<endl; };

    ???//通過這種方式操作myv中的值

    ???for_each(myv.begin(),myv.end(),fun1);

    ?

    ???cout <<"----------------" <<endl;

    ?

    ???//直接寫在內部,下面的v表示傳遞進lambda表達式的參數

    ???for_each(myv.begin(),myv.end(),[](intv)

    ???{

    ??????cout <<v <<endl;

    ???});

    ?

    ???std::cin.get();

    }

    運行結果:

    案例3

    #include<functional>

    #include<iostream>

    #include<vector>

    #include<algorithm>

    ?

    usingnamespacestd;

    ?

    voidmain()

    {

    ???vector<int>?myv;

    ???myv.push_back(1);

    ???myv.push_back(2);

    ???myv.push_back(11);

    ?

    ???inta = 10;

    ???// =知道a的存在,可以引用,只能讀,不可以寫,引用當前塊語句內部的局部變量

    ???autofun1 = [=](intv){v +=a;?cout <<v <<endl;?};

    ?

    ???for_each(myv.begin(),myv.end(),fun1);

    ???//此時a沒有被修改

    ???cout <<a <<endl;

    ???std::cin.get();

    }

    運行結果:

    案例4

    #include<functional>

    #include<iostream>

    #include<vector>

    #include<algorithm>

    ?

    usingnamespacestd;

    ?

    voidmain()

    {

    ???vector<int>?myv;

    ???myv.push_back(1);

    ???myv.push_back(2);

    ???myv.push_back(11);

    ?

    ???inta = 10;

    ???//引用變量a,相當于直接操作a

    ???autofun1 = [&a](intv){a = 3; v +=a;?cout <<v <<endl;?};

    ?

    ???for_each(myv.begin(),myv.end(),fun1);

    ???//此時a發生變化

    ???cout <<a <<endl;

    ???std::cin.get();

    }

    運行結果:

    案例5

    #include<functional>

    #include<iostream>

    #include<vector>

    #include<algorithm>

    ?

    usingnamespacestd;

    ?

    voidmain()

    {

    ???[](){cout <<"hellochina"; };//是一個函數指針

    ???[](){cout <<"hellochina";}();//如果沒有定義名稱,如果想調用lambda表達式,可以直接在lambda表達式的最后面加上()

    ?

    ???cin.get();

    }

    運行結果:

    案例6

    #include<functional>

    #include<iostream>

    #include<vector>

    #include<algorithm>

    ?

    usingnamespacestd;

    ?

    classtest

    {

    public:

    ???vector<int>?myv;

    ???intnum;

    public:

    ???voidadd()

    ???{

    ???????num = 12;

    ???????myv.push_back(10);

    ???????myv.push_back(11);

    ?

    ???????//[]引用this

    ???????int?x = 3;

    ???????autofun1 = [this,x](intv){cout <<v+x+this->num << endl; };

    ???????//=按照副本引用this,還有當前塊語句局部變量,不可以賦值,但是可以讀取

    ???????//&按照引用的方式操作局部變量,this,可以賦值,可以讀取

    ???????//副本引用a,[=]??[a]

    ???????//引用a [&]?[&a]

    ?

    ???????autofun2 = [&](intv){cout <<v +x +this->num << endl;x = 3; };

    ???????for_each(this->myv.begin(),this->myv.end(),fun1);

    ???????cout <<"-----------------" <<endl;

    ???????for_each(this->myv.begin(),this->myv.end(),fun2);

    ???}

    };

    ?

    voidmain()

    {

    ???testt;

    ???t.add();

    ?

    ???cin.get();

    }

    運行結果:

    :7

    #include<functional>

    #include<iostream>

    #include<vector>

    #include<algorithm>

    ?

    usingnamespacestd;

    //返回值案例

    voidmain()

    {

    ???//double是返回值類型

    ???autofun1 = []()->double{cout << "hello china" <<endl;return 1; };

    ???fun1();

    ?

    ???//通過decltype(a/b)的方式獲得類型

    ???autofun2 = [](inta,doubleb)->decltype(a / b){cout << "hello china" <<endl;returna /b; };

    ???fun2(1, 2.3);

    ?

    ???std::cin.get();

    }

    運行結果:

    案例8

    #include<functional>

    #include<iostream>

    #include<vector>

    #include<algorithm>

    ?

    usingnamespacestd;

    ?

    void?main()

    {

    ???inta = 10;

    ???//mutable使可以改副本了。如果下面的去掉將會報錯

    ???autofun1 = [a](intv)mutable->double{v += a;?cout <<v <<endl;a = 3;return 3; };

    ???cout <<a <<endl;

    ?

    ???std::cin.get();

    ???//運行結果還是10

    }


    Lambada表達式補充

    {

    ??????? auto func = []{return 1; };

    ??????? int i = func();

    ??????? CCLog("i = %d", i);

    ??? }

    ??? //最簡單的lambada表達式是只要一個中括號和一個大括號

    ??? //[]捕獲列表

    ??? //{}函數體

    ??? //1.捕獲列表,可以放變量名,這里可以用來傳遞函數體內定義的變量

    ??? {

    ??????? int v = 100;

    ??????? auto func = [v]{return v; };

    ??????? int x = func();

    ??? }

    ?

    ??? //2.捕獲列表,可以捕獲多個變量

    ??? {

    ??????? int p = 100, q = 200;

    ??????? auto func = [p, q]{return p + q; };

    ??????? int s = func();

    ??? }

    ?

    ??? // 3.捕獲列表,有引用和傳值兩種方式,傳值不可以改變,引用可以改變,并且改變外部的變量值

    ??? {

    ??????? int p = 100, q = 200;

    ??????? auto func = [p, &q]{q++;? return p + q; };

    ??????? int s = func();

    ??? }

    ?

    ??? //4.捕獲列表,可以定義mutable類型的lambada,能改變傳值的捕獲參數,

    ??? //但是不能改變外部的變量值

    ??? {

    ??????? int p = 100, q = 200;

    ??????? auto func = [p, q]()mutable{p++; q++; return p + q; };

    ??????? int s = func();

    ??????? CCLog("p = %d,q = %d,s = %d", p, q, s);

    ??? }

    ?

    ??? //5.捕獲列表,可以用=或者&捕獲所有變量,=指傳值,&表示引用

    ??? {

    ??????? int p = 100, q = 200;

    ??????? //用&的時候,所有的都可以調用了,[&,p]:表示除了p不能被使用,其它的都可以被使用

    ??????? auto func = [&]{

    ??????????? return p + q;

    ??????? };

    ??? }

    ?

    ??? //稍微復雜點的lambda表達式

    ??? {

    ??????? auto add = [](int v1, int v2){return v1 + v2; };

    ??????? auto a = add(1 , 2);

    ??? }

    ?

    ??? //小括號中的是參數列表,參數列表和捕獲列表區別在于,參數列表的參數由調用方決定,

    ??? //捕獲列表由定義方決定,所以更加靈活

    ?

    ??? //更加復雜的lambada表達是,有返回值,返回值一般都省略

    ??? {

    ??????? //->int表示返回值是int類型的

    ??????? auto add = [](int v1, int v2)->int{return v1 + v2; };

    ??? }

    ?

    ??? //總結:auto func = [](){}

    ??? {

    ??????? auto func = [](){};

    ??? }

    ?

    ?


    總結

    以上是生活随笔為你收集整理的lambada表达式的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。