有時候,我們會需要將乙個函式作為變元傳遞給另乙個函式,這時,就需要了解函式指標的作用了
先來回顧一下函式指標:
函式指標不同於普通指標,它儲存的內容還包括乙個函式的返回型別和引數列表,形式為:
返回型別( * 函式指標名 ) (引數列表),當乙個函式指標建立後,它就只能指向對應返回型別和引數型別的函式,無法指向其他型別函式。
為了方便和正確起見,我們可以利用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...