C++11中的Lambda表達式用于 定義并創建匿名的函數對象 ,以簡化編程工作。下面看一下Lambda表達式的基本構成。
基本構成
首先是Lambda的基本結構:
capture mutable ->return-type
{
statement
}
整體的結構可以表示為:函數對象參數mutable ->返回值{函數體}。下面依次介紹各個部分的定義及用法。
函數對象參數
[] ,用這個方括號標識一個Lambda表達式的開始,這一部分 必須存在,不能省略 。函數對象參數是傳遞給編譯器自動生成的函數對象類的構造函數的。函數對象參數只能使用那些到定義Lambda為止時Lambda所在作用范圍內可見的 局部變量 (包括Lambda所在類的this)。
int a=1;
[](){
cout<endl;
}();
在這個例子中,函數對象為空,訪問不到a,程序會報錯。(最后加一個括號是直接調用)函數對象參數有以下形式:
- 空。沒有使用任何函數對象參數。
- =。函數體內可以使用Lambda所在作用范圍內所有可見的局部變量(包括Lambda所在類的this),并且是 值傳遞方式 (相當于編譯器自動為我們按值傳遞了所有局部變量)。 這種方式最為常用 。
- &。函數體內可以使用Lambda所在作用范圍內所有可見的局部變量(包括Lambda所在類的this),并且是 引用傳遞方式 (相當于編譯器自動為我們按引用傳遞了所有局部變量)。
- this。函數體內可以使用Lambda所在類中的成員變量。
- a。將a按值進行傳遞。按值進行傳遞時,函數體內不能修改傳遞進來的a的拷貝,因為默認情況下函數是const的。要修改傳遞進來的a的拷貝,可以添加mutable修飾符。
- &a。將a按引用進行傳遞。=,&a, &b。除a和b按引用進行傳遞外,其他參數都按值進行傳遞。? &, a, b。除a和b按值進行傳遞外,其他參數都按引用進行傳遞。
常用的方式就第二種和第三種。其它的方式根據具體的情況進行選擇。
操作符重載函數參數
標識重載的()操作符的參數,沒有參數時,這部分可以省略。參數可以通過按值(如:(a,b))和按引用(如:(&a,&b))兩種方式進行傳遞。這個就類似與普通函數的形參。
可修改標示符
mutable聲明,這部分可以省略。按值傳遞函數對象參數時,加上mutable修飾符后,可以修改按值傳遞進來的拷貝(注意是能修改拷貝,而不是值本身)。
int a=1;
//不可修改
[=](){
a=2;
}();
//可以修改
[=]()mutable{
a=2;
}();
只是對值的拷貝進行修改,函數外部變量的值仍未改變。
函數返回值
->返回值類型,標識函數返回值的類型,當返回值為void,或者函數體中只有一處return的地方(此時編譯器可以自動推斷出返回值類型)時,這部分可以省略。
函數體
{},標識函數的實現,這部分不能省略,但函數體可以為空。
Lambda作為返回值
在C++11中只能使用std::function指定返回值,將欲返回的lambda表達式轉換成function對象。
auto num = [](int i, int j){ return i - j; };
int main(){
cout<1,2);
}
上述是將Lambda作為一個對象,然后用auto自動轉換類型,同時可以指定類型也就是function對象。
function<int(int,int)> num = [](int i, int j){ return i - j; };
cout<1,2);
這個模板對象中需要傳入函數返回值類型和形參類型,通常使用auto進行自動轉換。
std::function<void(int)> func(){
return [] (int e) { std::cout << e; };
}
func()(10);
這個例子是將Lambda作為函數的返回值。
總結
Lambda還有許多種用處,通常也可以作為STL種算法的參數傳入,用于處理一些邏輯較為簡單的函數結構,例如比較大小等。
std::sort(v.begin(), v.end(), [] ( int n1, int n2 ) { return n1 > n2; });
這個例子就是用sort算法,并利用Lambda進行排序。
審核編輯:湯梓紅
-
函數
+關注
關注
3文章
4331瀏覽量
62622 -
C++
+關注
關注
22文章
2108瀏覽量
73653 -
Lambda
+關注
關注
0文章
29瀏覽量
9879
發布評論請先 登錄
相關推薦
評論