技術(shù)交流QQ群:1027579432综芥,歡迎你的加入!
1.Lambda函數(shù)與表達(dá)式
C++11提供了對(duì)匿名函數(shù)的支持,稱為L(zhǎng)ambda函數(shù)(也叫Lambda表達(dá)式)沦泌。Lambda表達(dá)式把函數(shù)看作對(duì)象溉痢。Lambda表達(dá)式可以像對(duì)象一樣使用,比如可以將它們賦給變量和作為參數(shù)傳遞包雀,還可以像函數(shù)一樣對(duì)其求值宿崭。Lambda 表達(dá)式本質(zhì)上與函數(shù)聲明非常類似,Lambda表達(dá)式具體形式如下:
[capture](parameters) mutable ->return-type{statement}
例如:
[](int a, int b) -> int { return a + b; };
參數(shù)介紹:
[capture]:捕捉列表。捕捉列表總是出現(xiàn)在lambda表達(dá)式的開(kāi)始處才写。事實(shí)上葡兑,[]是lambda引出符。編譯器根據(jù)該引出符判斷接下來(lái)的代碼是否是lambda函數(shù)赞草。捕捉列表能夠捕捉上下文中的變量供lambda函數(shù)使用讹堤。
(parameters):參數(shù)列表。與普通函數(shù)的參數(shù)列表一致厨疙。如果不需要參數(shù)傳遞洲守,則可以連同括號(hào)()一起省略。
mutable:mutable修飾符沾凄。默認(rèn)情況下梗醇,lambda函數(shù)總是一個(gè)const函數(shù),mutable可以取消其常量性搭独。在使用該修飾符時(shí)婴削,參數(shù)列表不可省略(即使參數(shù)為空)。
->return_type:返回類型牙肝。用追蹤返回類型形式聲明函數(shù)的返回類型唉俗。出于方便,不需要返回值的時(shí)候也可以連同符號(hào)->一起省略配椭。此外虫溜,在返回類型明確的情況下,也可以省略該部分股缸,讓編譯器對(duì)返回類型進(jìn)行推導(dǎo)衡楞。
{statement}:函數(shù)體。內(nèi)容與普通函數(shù)一樣敦姻,不過(guò)除了可以使用參數(shù)之外瘾境,還可以使用所有捕獲的變量。在lambda函數(shù)的定義式中镰惦,參數(shù)列表和返回類型都是可選部分迷守,而捕捉列表和函數(shù)體都可能為空,C++中最簡(jiǎn)單的lambda函數(shù)只需要聲明為:[]{};
// 定義一個(gè)簡(jiǎn)單的lambda表達(dá)式
auto basicLamda = [] {cout << "hello world!" << endl; };
basicLamda(); // 調(diào)用
// 如果需要參數(shù)旺入,那么就要像函數(shù)那樣兑凿,放在圓括號(hào)里面凯力,如果有返回值,返回類型要放在->后面礼华,即拖尾返回類型
// 當(dāng)然你也可以忽略返回類型咐鹤,lambda會(huì)幫你自動(dòng)推斷出返回類型
auto add = [](int a, int b) -> int {return a + b; };
int result = add(4, 5);
cout << "result = " << result << endl;
// 自動(dòng)推斷出返回類型
auto multiply = [](int a, int b) {return a * b; };
int result1 = multiply(5, 6);
cout << "result1 = " << result1 << endl;
在Lambda表達(dá)式內(nèi)可以訪問(wèn)當(dāng)前作用域的變量,這是Lambda表達(dá)式的閉包(Closure)行為圣絮。C++變量傳遞有傳值和傳引用的區(qū)別祈惶。可以通過(guò)前面的[]來(lái)指定:
[] // 沒(méi)有定義任何變量晨雳。使用未定義變量會(huì)引發(fā)錯(cuò)誤
[x, &y] // x以傳值方式傳入(默認(rèn))行瑞,y以引用方式傳入
[&] // 任何被使用到的外部變量都隱式地以引用方式加以引用
[=] // 任何被使用到的外部變量都隱式地以傳值方式加以引用
[&, x] // x顯式地以傳值方式加以引用。其余變量以引用方式加以引用
[=, &z] // z顯式地以引用方式加以引用餐禁。其余變量以傳值方式加以引用
對(duì)于[=]或[&]的形式血久,lambda表達(dá)式可以直接使用this指針。但是帮非,對(duì)于[]的形式氧吐,如果要使用this指針,必須顯式傳入:[this]() { this->someFunc(); }();
#include "iostream"
using namespace std;
class Test{
public:
void hello(){
cout << "test hello!\n";
};
void lambda(){
auto fun = [this]{ // 捕獲了 this 指針
this->hello();
}; // 這里 this 調(diào)用的就是 class Test 的對(duì)象了
fun();
}
};
int main(){
// 定義一個(gè)簡(jiǎn)單的lambda表達(dá)式
auto basicLamda = [] {cout << "hello world!" << endl; };
basicLamda(); // 調(diào)用
// 如果需要參數(shù)末盔,那么就要像函數(shù)那樣筑舅,放在圓括號(hào)里面,如果有返回值陨舱,返回類型要放在->后面翠拣,即拖尾返回類型
// 當(dāng)然你也可以忽略返回類型,lambda會(huì)幫你自動(dòng)推斷出返回類型
auto add = [](int a, int b) -> int {return a + b; };
int result = add(4, 5);
cout << "result = " << result << endl;
// 自動(dòng)推斷出返回類型
auto multiply = [](int a, int b) {return a * b; };
int result1 = multiply(5, 6);
cout << "result1 = " << result1 << endl;
// 1游盲、什么也不捕獲误墓,或者是故意不用 Lambda 函數(shù)外部的變量
int i = 1024;
// auto f = []{cout << "i = " << i << endl; }; 報(bào)錯(cuò)!應(yīng)該使用了lambda函數(shù)外部的變量
auto f = [=] { cout << "i = " << i << endl; }; // 使用傳值的方式使用外lambda函數(shù)外部的變量i
f(); // 調(diào)用函數(shù)
// 2、引用捕捉
int i1 = 666;
cout << "變量i1的引用: " << &i1 << endl;
auto f1 = [&] { cout << "變量i1的引用: " << &i1 << endl; };
f1();
// 3益缎、復(fù)制并引用捕獲
int i2 = 777, j2 = 888;
cout << "i2 = " << i2 << endl;
cout << "j2 = " << j2 << endl;
auto f2 = [=, &i2] { cout << "i2 = " << &i2 << " ,j2 = " << &j2 << endl; }; // 默認(rèn)拷貝外部所有變量谜慌,但引用變量i2
f2();
// 4、指定引用或復(fù)制
int i3 = 444, j3 = 555;
cout << "外部變量i3 = " << i3 << " i3的地址是: " << &i3 << endl;
auto f3 = [i3] { cout << "內(nèi)部變量i3 = " << i3 << " i3的地址是: " << &i3 << endl; };
f3();
// 5莺奔、捕獲this指針
Test t;
t.lambda();
return 0;
}
最后編輯于 :2020.01.11 20:20:03
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者