lambda:
C++11提供了對匿名函數的支持,稱為Lambda函數(也叫Lambda表達式). Lambda表達式具體形式如下:
匿名函數定義/匿名表達式聲明:[capture](parameters)->return-type{body}
函數調用:function a = [capture](parameters)->return-type{body};
a(parameters);
parameters:形參
和函數一樣
如果沒有參數,空的圓括號()可以省略.
返回值也可以省略,如果函數體只由一條return語句組成或返回類型為void的話.形如:
[capture](parameters){body}
返回值類型可以通過以下算法推演出來
-
- 如果 lambda 代碼塊中包含了 return 語句,則該 lambda 表達式的返回類型由 return 語句的返回類型確定。
- 如果沒有 return 語句,則類似 void f(...) 函數。
例如:
[](int x, int y) { return x + y; } // 隱式返回類型 [](int& x) { ++x; } // 沒有return語句 -> lambda 函數的返回類型是'void' []() { ++global_x; } // 沒有參數,僅訪問某個全局變量 []{ ++global_x; } // 與上一個相同,省略了()
[]:外部閉包
Lambda函數可以引用在它之外聲明的變量. 這些變量的集合叫做一個閉包. 閉包被定義在Lambda表達式聲明中的方括號[]內.
閉包可以按值、引用捕獲:
例如:
[] //未定義變量.試圖在Lambda內使用任何外部變量都是錯誤的. [x, &y] //x 按值捕獲, y 按引用捕獲. [&] //用到的任何外部變量都隱式按引用捕獲 [=] //用到的任何外部變量都隱式按值捕獲 [&, x] //x顯式地按值捕獲. 其它變量按引用捕獲 [=, &z] //z按引用捕獲. 其它變量按值捕獲
對this的捕獲:只可以是值捕獲,
在類成員中的lamda函數:
對protect和priviate成員來說, 這個lambda函數與創建它的成員函數有相同的訪問控制.
訪問this的成員不必使用this->語法,可以直接訪問.
注意:如果一個閉包含有局部變量(類和局部)的引用,在超出創建它的作用域之外的地方被調用的話,這種行為是未定義的!
lambda函數是一個依賴於實現的函數對象類型,這個類型的名字只有編譯器知道.
如果用戶想把lambda函數做為一個參數來傳遞, 那么形參的類型必須是模板類型或者必須能創建一個std::function類似的對象去捕獲lambda函數.
使用 auto關鍵字可以幫助存儲lambda函數,