C++ lamda表達式


    lamda表達式是C++11中的新特征,說白了就是匿名函數。
    
    lambda表達式的具體形式如下:


        [capture](parameters)->return-type{body}



     其中, capture是需要用到的外部變量, parameters是函數參數,return-type是返回的類型(可省略),body是函數體。


    來個最簡單的:

    

[](){};

 

 ”[]"表示不需要使用外部變量,”()"表示形參列表為空,"{}"表示空函數,什么都不干。

    再舉一個例子。
    在STL中有一個排序函數std::sort,如果現在我們要用它來按降序排列一個數組arr,則可自定義一個比較函數cmp,並把它傳給sort函數,如下

 

 bool cmp(int a, int b) {

    return a > b;

  }

  std::sort(arr, arr + len, cmp);

  

  若果使用lamda表達式,則可改寫成如下

std::sort(arr, arr + len, [](int a, int b) {

    return a > b;

  });

 


 

  

 

  "[]"表明沒有用到外部變量,如果我們要用到外部變量,則要對"[]"進行修改,如下代碼

 

  int n = 10;

  [](int a) {return a + n;}; // 報錯,提示變量n不能在lamda體中調用,除非其在捕獲列表中

 

  捕獲列表是指"[]",因此我們在"[]"中加上n即可。如下

  int n = 10;

  [n](int a) {return a + n;}; // 正確

  "[n]"說明n是以傳值的方式傳到lamda體中,傳值和傳引用的差別請自行百度。捕獲列表可按如下規則傳入

  • [] 什么也沒有捕獲
  • [a, &b] 按值捕獲a,按引用捕獲b
  • [&] 按引用捕獲任何用到的外部變量
  • [=] 按值捕獲任何用到的外部變量
  • [a, &] 按值捕獲a, 其它的變量按引用捕獲
  • [&b, =] 按引用捕獲b,其它的變量按值捕獲
  • [this] 按值捕獲this指針

 

  注意: 假如我們想修改按值傳進來的形參,將會發生錯誤,因為按值捕獲的對象不能被修改,如下代碼

 

   int n = 10;
    [n](int a) {
        n += a; // 報錯,提示不允許修改n的值
        return n;
    };

 

  

  這時我們需要假如一個mutable,如下

    int n = 10;
    [n](int a)mutable {
        n += a; // 正確
        return n;
    };

 


  關於返回值類型,可由以下規則推導出來

  • 如果body僅包含單一的return語句,那么返回值類型是返回表達式的類型(在此隱式轉換之后的類型:右值到左值、數組與指針、函數到指針)
  • 否則,返回類型是void

  譬如我們上面std::sort()的這個例子,lamda表達式是

[](int a, int b) {return a > b;};

  a > b 這個表達式返回的類型是bool,因此這個lamda表達式返回類型是bool。

  最后一個例子,我們可以把lamda表達式進行賦值,還是利用std::sort()這個例子。我們可以把cmp函數寫成如下

std::function<bool(int, int)> cmp = [](int a, int b) {return a > b;};  //std::function包含在頭文件functional中,具體用法請自行百度

  這樣做的好處是可以多次利用lamda表達式。當然,我們可以指定其返回類型為auto,來讓其自行判斷。

auto cmp = [](int a, int b) {return a > b;};

  


  lamda表達式的簡單介紹到此結束。文章若有錯漏之處,請提出,多謝。

  

  參考:

    Lambda函數(C++11 起):http://zh.cppreference.com/w/cpp/language/lambda
    代碼簡潔之道:C++ 11 之auto+ for_each + lamda表達式:http://www.itnose.net/detail/6090413.html

 

  

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM