c++11提供了對匿名函式的支援,稱為lambda函式(也叫lambda表示式). lambda表示式具體形式如下:
[capture](parameters)->return-type
如果沒有引數,空的圓括號()可以省略.返回值也可以省略,如果函式體只由一條return語句組成或返回型別為void的話.形如:
[capture](parameters)
下面舉了幾個lambda函式的例子:
(int x, int y) // 隱式返回型別
(int& x) // 沒有return語句 -> lambda 函式的返回型別是'void'
() // 沒有引數,僅訪問某個全域性變數
// 與上乙個相同,省略了()
可以像下面這樣顯示指定返回型別:
(int x, int y) -> int
在這個例子中建立了乙個臨時變數z來儲存中間值. 和普通函式一樣,這個中間值不會儲存到下次呼叫. 什麼也不返回的lambda函式可以省略返回型別, 而不需要使用 -> void 形式.
lambda函式可以引用在它之外宣告的變數. 這些變數的集合叫做乙個閉包. 閉包被定義在lambda表示式宣告中的方括號內. 這個機制允許這些變數被按值或按引用捕獲.下面這些例子就是:
//未定義變數.試圖在lambda內使用任何外部變數都是錯誤的.
[x, &y]
//x 按值捕獲, y 按引用捕獲.
[&]//用到的任何外部變數都隱式按引用捕獲
[=]//用到的任何外部變數都隱式按值捕獲
[&, x]
//x顯式地按值捕獲. 其它變數按引用捕獲
[=, &z]
//z按引用捕獲. 其它變數按值捕獲
接下來的兩個例子演示了lambda表示式的用法.
複製**
some_list; hljs matlab">int total = 0;
for (int i=0;i
<5;++i) some_list.push_back(i);
std::for_each(begin(some_list), end(some_list), [&total](int x)
);
此例計算list中所有元素的總和. 變數total被存為lambda函式閉包的一部分. 因為它是棧變數(區域性變數)total的引用,所以可以改變它的值.
std::vector
some_list;
int total = 0;
int value = 5;
std::for_each(begin(some_list), end(some_list), [&, value, this](int x)
);
此例中total會存為引用, value則會存乙份值拷貝. 對this的捕獲比較特殊, 它只能按值捕獲. this只有當包含它的最靠近它的函式不是靜態成員函式時才能**獲.對protect和priviate成員來說, 這個lambda函式與建立它的成員函式有相同的訪問控制. 如果this**獲了,不管是顯式還隱式的,那麼它的類的作用域對lambda函式就是可見的. 訪問this的成員不必使用this->語法,可以直接訪問.
不同編譯器的具體實現可以有所不同,但期望的結果是:按引用捕獲的任何變數,lambda函式實際儲存的應該是這些變數在建立這個lambda函式的函式的棧指標,而不是lambda函式本身棧變數的引用. 不管怎樣, 因為大數lambda函式都很小且在區域性作用中, 與候選的內聯函式很類似, 所以按引用捕獲的那些變數不需要額外的儲存空間.
如果乙個閉包含有區域性變數的引用,在超出建立它的作用域之外的地方被使用的話,這種行為是未定義的!
lambda函式是乙個依賴於實現的函式物件型別,這個型別的名字只有編譯器知道. 如果使用者想把lambda函式做為乙個引數來傳遞, 那麼形參的型別必須是模板型別或者必須能建立乙個std::function類似的物件去捕獲lambda函式.使用 auto關鍵字可以幫助儲存lambda函式,
auto my_lambda_func = [&](int x) ;
auto my_onheap_lambda_func = new auto([=](int x) );
這裡有乙個例子, 把匿名函式儲存在變數,陣列或vector中,並把它們當做命名引數來傳遞
#include
#include
#include
double eval(std::function f, double x = 2.0)
int main()
; auto f1 = (double x);
decltype(f0) fa[3] = };
std::vector
fv = ;
fv.push_back ((double x));
for(int i=0;istd::cout
<< fv[i](2.0) << "\n";
for(int i=0;i<3;i++) std::cout
<< fa[i](2.0) << "\n";
for(auto &f : fv) std::cout
<< f(2.0) << "\n";
for(auto &f : fa) std::cout
<< f(2.0) << "\n";
std::cout
<< eval(f0) << "\n";
std::cout
<< eval(f1) << "\n";
return
0;}
乙個沒有指定任何捕獲的lambda函式,可以顯式轉換成乙個具有相同宣告形式函式指標.所以,像下面這樣做是合法的:
auto a_lambda_func = (int x) ;
void(*func_ptr)(int) = a_lambda_func;
func_ptr(4); //calls the lambda.
Lambda和Stream流知識點
一 函式式介面,滿足條件 函式式介面 functionalinte ce public inte ce functioninte ce 二 引數的傳遞public void test 三 編寫特性 public void test collect collectors.joining system....
函式知識點
1.函式 函式就是一種封裝 2.定義函式 function 函式名 3.函式不會自動執行,需要被呼叫才可以執行 函式名 4.函式命名規則 與變數命名規則一致 1 以字母 開頭 2 可以包含數字 字母 3 區分大小寫 4 不能使用關鍵字和保留字 駝峰命名法 若名稱由多個單詞組成,則從第二個單詞開始,首...
函式知識點
今日主要內容 函式 一,函式的概念 函式就是對一些重複使用的功能的封閉 二,函式的組成部分 1,函式名 是程式使用函式的依據 2,函式體 是實現功能的具體 塊 3,函式返回值 功能實現的結果 4,函式引數 實現功能的條件 三,函式的定義 函式需要先定義,再呼叫 def 函式申明的關鍵字 例 def ...