c++匿名函數使用方法
1、匿名函數的使用
匿名函數的基本語法為:
//[捕獲列表](參數列表)->返回類型{函數體}
int main()
{
auto Add = [](int a, int b)->int {
return a + b;
};
std::cout << Add(1, 2) << std::endl;
return 0;
}
上述代碼便會輸出3,這就是匿名函數的使用方法。
注意點:一般情況下,編譯器可以自動推斷出lambda表達式的返回類型,所以我們可以不指定返回類型,即:
//[捕獲列表](參數列表){函數體}
int main()
{
auto Add = [](int a, int b) {
return a + b;
};
std::cout << Add(1, 2) << std::endl;
return 0;
}
但是如果函數體內有多個return語句時,編譯器無法自動推斷出返回類型,此時必須指定返回類型
2、什么是捕獲列表?
試圖在Lambda內使用外部變量是錯誤的,例如:
#include <iostream>
int main()
{
int c = 12;
auto Add = [](int a, int b)->int {
return c;
};
std::cout << Add(1, 2) << std::endl;
return 0;
}
但是有些時候我們需要使用外部變量,所以需要使用捕獲列表,上述代碼改寫成一下形式便可以通過編譯。
#include <iostream>
int main()
{
int c = 12;
auto Add = [c](int a, int b)->int {
return c;
};
std::cout << Add(1, 2) << std::endl;
return 0;
}
但是如果你更改一下lambda表達式中代碼塊的內容,比如在上述代碼中添加一句
c = a;
這樣又會無法編譯通過了,因為你的c是按值傳遞的,所以要將捕獲列表改成
[&c](int a, int b)->int{……};
這樣c的值便是按引用傳遞了,便可以進行修改。
補充知識:
- 如果捕獲列表為[&],則表示所有的外部變量都按引用傳遞給lambda使用
- 如果捕獲列表為[=],則表示所有的外部變量都按值傳遞給lambda使用
- 匿名函數構建的時候對於按值傳遞的捕獲列表,會立即將當前可以取到的值拷貝一份作為常數,然后將該常數作為參數傳遞,即:
int main()
{
int c = 12;
//Add構建的時候實際是:[12](int a,int b)->int{}
auto Add = [c](int a, int b)->int {
return c;
};
std::cout << Add(1, 2) << std::endl;
return 0;
}
到此,匿名函數(Lambda表達式)的基礎使用方法就介紹完畢了
3、一些”廢話“
在這一小節中,我們會提一些和Lambda有關的知識。
3.1、介紹Lambda
一個Lambda表達式表示一個可調用的代碼單元,我們可以將它理解為一個未命名的內聯函數。和任何函數類似,一個Lambda表達式具有一個返回類型,一個參數列表和一個函數體,但和普通函數不一樣的是Lambda表達式可能定義在函數內部。我們可以忽略Lambda表達式的參數列表和返回類型,但不可以忽略捕獲列表和函數體
//
//這是正確的(忽略了參數列表和返回類型)
//
//為什么沒有指定返回類型還可以返回整數值?
//因為你的函數體有return語句,它可以推斷出來
auto f = []{ return 1 + 2; };
3.2、Lambda捕獲列表
[] | 空捕獲列表,Lambda不能使用所在函數中的變量。 |
---|---|
[names] | names是一個逗號分隔的名字列表,這些名字都是Lambda所在函數的局部變量。默認情況下,這些變量會被拷貝,然后按值傳遞,名字前面如果使用了&,則按引用傳遞 |
[&] | 隱式捕獲列表,Lambda體內使用的局部變量都按引用方式傳遞 |
[=] | 隱式捕獲列表,Lanbda體內使用的局部變量都按值傳遞 |
[&,identifier_list] | identifier_list是一個逗號分隔的列表,包含0個或多個來自所在函數的變量,這些變量采用值捕獲的方式,其他變量則被隱式捕獲,采用引用方式傳遞,identifier_list中的名字前面不能使用&。 |
[=,identifier_list] | identifier_list中的變量采用引用方式捕獲,而被隱式捕獲的變量都采用按值傳遞的方式捕獲。identifier_list中的名字不能包含this,且這些名字面前必須使用&。 |
參考資料:《C++ Primer(第五版)》