C 傳遞lambda表示式給函式

2021-09-25 09:23:15 字數 3032 閱讀 7574

有時候,我們會需要將乙個函式作為變元傳遞給另乙個函式,這時,就需要了解函式指標的作用了

先來回顧一下函式指標:

函式指標不同於普通指標,它儲存的內容還包括乙個函式的返回型別和引數列表,形式為:

返回型別( * 函式指標名 ) (引數列表),當乙個函式指標建立後,它就只能指向對應返回型別和引數型別的函式,無法指向其他型別函式。

為了方便和正確起見,我們可以利用auto關鍵字讓編譯器自動識別函式型別並建立相應的函式指標,如:

int

add(

int a,

int b)

intmain()

而對於乙個沒有任何捕獲子句的lambda表示式,其可以賦值給乙個函式指標,如下面語句是合法的:

auto padd =

(int a,

int b)

->

int;

//左為函式指標,右為lambda表示式

所以,當我們想將函式作為變元傳遞時,我們就可以將對應的函式指標傳遞過去。而對於lambda表示式而言,它本身是乙個匿名函式,因此也可以賦值給函式指標然後傳遞過去。那麼lambda表示式能不能直接作為變元傳遞而不依靠函式指標呢?

解答:首先可以肯定的答案是,lambda表示式是可以作為引數傳遞的,但並非想象中那麼直接。

在被調函式中,我們通常會使用乙個函式指標來接受主調函式傳遞過來的lambda表示式,但是參考前面函式指標形式可以發現,我們必須事先確定好函式指標的型別才能建立乙個函式指標,這就包括返回型別和引數列表而每次lambda表示式的型別可能都是不一樣的,這就要求我們每次都改變相對應的函式指標來接受lambda表示式,這相當麻煩。

所以,乙個簡單的方法就是建立乙個函式指標模板,來接受任意型別的lambda表示式。編譯器會自動推斷在模板例項使用的引數型別。

函式指標模板:

//通過function函式對vector中每乙個元素呼叫傳遞過來的lambda表示式,即fun()

template

void

function

(std:

:vector<

int>

&data, f fun)

}

呼叫函式模板的語句可以為:

std:

:vector<

int>data

;function

(data,

(int x)

->

int)

;//返回x的平方

for(

const

auto

& value : data)

std:

:cout << value << std:

:endl;

此時編譯器自動識別 fun 的型別為 int( * ) ( int ) ,因此成功傳遞lambda表示式!

不過,當表示式中引導[ ] 非空時,採用這種方式傳遞 lambda 表示式是不安全的,因為 lambda 引導包含的內容不僅會改變型別,還會顯著改變 lambda 表示式可以執行的操作。當然,針對這種問題,c++依然提供了一種有效的方法。

std::function 模板型別

標準庫中的標頭檔案functional定義了乙個模板型別 std::functional<> ,它是一組包含各種各樣型別的函式指標的包裝器,其中也包括lambda表示式,其形式為:std::function《返回型別(引數列表)>

首先,他可以用在被調函式中,用來宣告函式指標的型別,如:

//注意:這裡的function和std::function完全是兩個不同的東西,他們所屬的命名空間不同。前者是我們自己為被調函式取的名字,後者是標準庫里的固定的模板名。

//之所以取這個名字是因為這段**作用與前面幾個**作用完全相同,方便理解。

void

function

(std:

:vector<

int>

&data, std:

:function<

int(

int)

> fun)

}int

main()

;function

(data,[&

](int x)

->

int)

;for

(const

auto

& value : data)

std:

:cout << value << std:

:endl;

}

這樣仍顯得有些麻煩,因為我們還是要自己在被調函式中設定返回值和引數列表。不過,我們仍然可以為此建立乙個函式模板:

template 

void

function

(std:

:vector

&data, std:

:function<

void

(t)> fun)

}int

main()

; function<

int>

(data,[&

](int x)

->

int)

;//在<>內顯式指定型別

for(

const

auto

& value : data)

std:

:cout << value << std:

:endl;

}

不過在這個模板裡,我們無法讓編譯器自動識別 t 的型別,必須我們在呼叫時顯示指定,否則將無法編譯。

lambda表示式 lambda表示式

1.概述 c 11 中的 lambda 表示式用於定義並建立匿名的函式物件,以簡化程式設計工作。lambda 的語法形式如下 函式物件引數 操作符過載函式引數 mutable 或 exception 宣告 返回值型別可以看到,lambda 主要分為五個部分 函式物件引數 操作符過載函式引數 muta...

lambda表示式(函式)

lambda名稱來自lambda calculus,是一種使用匿名函式來定義和使用函式的數學系統。當某些函式比較簡單,只是臨時使用一下,便可以使用lambda表示式。1.定義及使用 例如 int x bool f3 int x 上面乙個是lambda表示式,乙個是函式,可以看出,代替了函式名,lam...

c 將lambda表示式作為引數傳遞

include int a 1 typeid a name c 11 提供了對匿名函式的支援,稱為 lambda 函式 也叫 lambda 表示式 lambda 表示式把函式看作物件。lambda 表示式可以像物件一樣使用,比如可以將它們賦給變數和作為引數傳遞,還可以像函式一樣對其求值。lambda...