lambda函式知識點

2021-08-07 14:20:58 字數 3177 閱讀 2336

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 ...