匿名函式(lambda)詳解 C++

Martin89發表於2018-03-22

匿名函式是許多程式語言都支援的概念,有函式體,沒有函式名,c++引入了lambda 函式,你可以在你的原始碼中內聯一個lambda函式,這就使得建立快速的,一次性的函式變得簡單了。

 

 

#include <algorithm>

#include <cmath>

void abssort(float* x, unsigned N) {

    std::sort(x, x + N,

        // Lambda expression begins

        [](float a, float b) {

            return std::abs(a) < std::abs(b);} ) }    

 

lambda函式形式

 

[capture_block](parameters) mutable exception_specification->return_type{ body } 

 

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

捕捉塊(catpure block): 指定如何捕捉所在作用域中的變數,並供給lambda主體使用。

引數(parameter): (可選)lambda表示式使用的引數列表。只有在不使用任何引數,並且沒有自定mutable、一個exception_specification 和一個return_type的情況下可以忽略該列表,返回型別在某些情況下也是可以忽略的,詳見對return_type的說明:eg: [] {return 10;}

引數列表和普通函式的引數列表類似,區別如下:

引數不能有預設值。

不允許變長引數列表。

不允許未命名的引數。

mutable:(可選)如果所在作用域的變數是通過值捕捉到,那麼lambda表示式主體中可以使用這些變數的副本。這些副本預設標記為const,因此lambda表示式的主體不能修改這些副本的值。如果lambda表示式標記為mutable,那麼這些副本則不是const,因此主體可以修改這些本地副本。

exception_specification:(可選)用於指定lambda可以丟擲的異常。

return_type:(可選)返回值的型別。如果忽略了return_type,那麼編譯器會根據以下原則判斷返回型別:

如果lambda表示式主體的形式為{return expression;}那麼表示式return_type的型別為expression的型別。

其他情況下的return_type為void。

下面的例子演示瞭如何建立一個lambda表示式並立即執行這個表示式。這行程式碼定義了一個沒有返回值也沒有任何引數的lambda表示式。

 

 

 

lambda函式能夠捕獲lambda函式外的具有自動儲存時期的變數。函式體與這些變數的集合合起來叫閉包。

  • [] 不擷取任何變數
  • [&} 擷取外部作用域中所有變數,並作為引用在函式體中使用
  • [=] 擷取外部作用域中所有變數,並拷貝一份在函式體中使用
  • [=, &foo] 擷取外部作用域中所有變數,並拷貝一份在函式體中使用,但是對foo變數使用引用
  • [bar] 擷取bar變數並且拷貝一份在函式體重使用,同時不擷取其他變數
  • [x, &y] x按值傳遞,y按引用傳遞
  • [this] 擷取當前類中的this指標。如果已經使用了&或者=就預設新增此選項。

相關文章