c++11特性,lambda表達式

首先引用百度百科裏面的內容:

Lambda表達式

 編輯 討論

“Lambda 表達式”(lambda expression)是一個匿名函數,Lambda表達式基於數學中的λ演算得名,直接對應於其中的lambda抽象(lambda abstraction),是一個匿名函數,即沒有函數名的函數。Lambda表達式可以表示閉包(注意和數學傳統意義上的不同)。

 

閉包

 編輯 討論10

本詞條由“科普中國”科學百科詞條編寫與應用工作項目 審覈 。

閉包就是能夠讀取其他函數內部變量的函數。例如在javascript中,只有函數內部的子函數才能讀取局部變量,所以閉包可以理解成“定義在一個函數內部的函數“。在本質上,閉包是將函數內部和函數外部連接起來的橋樑。 [1] 

lambda函數能夠捕獲lambda函數外的具有自動存儲時期的變量。函數體與這些變量的集合合起來叫閉包。
[] 不截取任何變量
[&} 截取外部作用域中所有變量,並作爲引用在函數體中使用
[=] 截取外部作用域中所有變量,並拷貝一份在函數體中使用
[=, &foo] 截取外部作用域中所有變量,並拷貝一份在函數體中使用,但是對foo變量使用引用
[bar] 截取bar變量並且拷貝一份在函數體重使用,同時不截取其他變量
[x, &y] x按值傳遞,y按引用傳遞
[this] 截取當前類中的this指針。如果已經使用了&或者=就默認添加此選項

C++表達式

編輯

ISO C++ 11 標準的一大亮點是引入Lambda表達式。基本語法如下:

1

[capture list] (parameter list) -> return type { function body }

其中除了“[ ]”(其中捕獲列表可以爲空)和“複合語句”(相當於具名函數定義的函數體),其它都是可選的。它的類型是單一的具有成員operator()的非聯合的類類型,稱爲閉包類型(closure type)。

C++中,一個lambda表達式表示一個可調用的代碼單元。我們可以將其理解爲一個未命名的內聯函數。它與普通函數不同的是,lambda必須使用尾置返回來指定返回類型。

例如調用<algorithm>中的std::sort,ISO C++ 98 的寫法是要先寫一個compare函數:

1

2

3

4

bool compare(int& a,int& b)

{

    return a>b;

}

然後,再這樣調用:

1

sort(a, a+n, compare);

然而,用ISO C++ 11 標準新增的Lambda表達式,可以這麼寫:

1

sort(a, a+n, [](int a,int b){return a>b;});//降序排序

這樣一來,代碼明顯簡潔多了。

由於Lambda的類型是單一的,不能通過類型名來顯式聲明對應的對象,但可以利用auto關鍵字和類型推導:

1

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

和其它語言的一個較明顯的區別是Lambda和C++的類型系統結合使用,如:

1

2

3

4

auto f=[x](int a,int b){return a>x;};//x被捕獲複製

int x=0, y=1;

auto g=[&](int x){return ++y;};//y被捕獲引用,調用g後會修改y,需要注意y的生存期

bool(*fp)(intint)=[](int a,int b){return a>b;};//不捕獲時纔可轉換爲函數指針

Lambda表達式可以嵌套使用。

即將出版的ISO C++14支持基於類型推斷的泛型lambda表達式。上面的排序代碼可以這樣寫:

1

sort(a, a+n, [](const auto& a,const auto& b){return a>b;});//降序排序:不依賴a和b的具體類型

因爲參數類型和函數模板參數一樣可以被推導而無需和具體參數類型耦合,有利於重構代碼;和使用auto聲明變量的作用類似,它也允許避免書寫過於複雜的參數類型。特別地,不需要顯式指出參數類型使使用高階函數變得更加容易。

 


 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章