釋放 C++ 中 Lambda 表達(dá)式的強(qiáng)大威力
?Lambda 是 C++ 中的匿名函數(shù)(即沒有函數(shù)名的函數(shù)),可以在定義和使用時內(nèi)聯(lián)。它們提供了一種方便的方式,將小的代碼塊作為參數(shù)傳遞給其他函數(shù),或者在不需要創(chuàng)建命名函數(shù)的情況下定義一個函數(shù)。
?Lambda 在 C++ 中提供了一種靈活而簡潔的方式來編寫類似函數(shù)的對象,并在現(xiàn)代 C++ 編程中被廣泛使用。
Lambda 的定義使用以下語法:
捕獲列表(capture list)用于指定 lambda 中可訪問的來自外部作用域的變量。變量可以通過值捕獲、引用捕獲或使用 this 捕獲。
- 參數(shù)列表(argument list)指定將遞給 lambda 的參數(shù)。
- 返回類型(return type)指定 lambda 將返回的值的類型。如果未指定,則編譯器將嘗試推斷其類型。
- 函數(shù)體(function body)指定 lambda 被調(diào)用時將執(zhí)行的代碼。
以下是在C++中使用 lambda 的幾種不同方式。
1、函數(shù)回調(diào)
函數(shù)回調(diào)是將一個函數(shù)作為參數(shù)傳遞給另一個函數(shù),并在接收函數(shù)稍后的時間調(diào)用該函數(shù)。您可以將 lambda 作為函數(shù)參數(shù)傳遞,其中它將在發(fā)生某個事件時執(zhí)行。
示例:
在這個例子中,sum 變量是一個Lambda表達(dá)式,它接受兩個參數(shù) a 和 b,并返回它們的總和。std::accumulate 函數(shù)接受數(shù)字向量、結(jié)果的初始值和 sum 函數(shù)(Lambda 表達(dá)式)。該函數(shù)計算向量中所有元素的總和并返回結(jié)果,該結(jié)果被打印在屏幕上。
另一個例子:
在這種情況下,lambda 表達(dá)式 [&sum](int x) { sum += x; } 被傳遞作為要應(yīng)用于每個元素的函數(shù)。lambda 通過引用 & 捕獲變量 sum,以便可以在 lambda 主體中進(jìn)行修改。
兩個例子都達(dá)到了相同的結(jié)果,但第二個例子使用了 std::for_each 算法和 lambda 表達(dá)式,這是在 C++ 中更現(xiàn)代、更簡潔的技術(shù)。
2、默認(rèn)捕獲
當(dāng)一個 lambda 表達(dá)式被聲明時沒有任何顯式的捕獲,其默認(rèn)行為是通過引用捕獲周圍作用域中的變量。這被稱為默認(rèn)捕獲。
例子:
在第二個例子中,定義了一個 lambda 表達(dá)式并將其存儲在名為 square 的變量中。這個 lambda 表達(dá)式接受一個 int 類型的參數(shù) x,并返回 x * x 的值,即參數(shù)的平方。
在主函數(shù)中,這個 lambda 表達(dá)式被用作函數(shù)對象。通過傳遞一個值為 5 的參數(shù)來調(diào)用它,并使用 cout 流顯示結(jié)果。
3、按值捕獲
這是 lambda 表達(dá)式的最簡單形式,其中你通過值傳遞變量給函數(shù)。當(dāng)一個變量被按值捕獲時,它的當(dāng)前值被存儲在閉包中,而當(dāng)周圍作用域中的變量發(fā)生改變時,它的值不會被更新。這可以通過將變量包含在方括號 [ ] 中來實(shí)現(xiàn)。
例子:
4、按引用捕獲
你可以通過使用 & 符號將變量傳遞給 lambda 表達(dá)式來按引用捕獲變量。當(dāng)一個變量被按引用捕獲時,它的當(dāng)前值被存儲在閉包中,并且在周圍作用域中變量發(fā)生變化時被更新。這是通過在方括號[ ]中在變量前加上取地址運(yùn)算符 & 來實(shí)現(xiàn)的。
例子:
5、可變Lambda表達(dá)式
默認(rèn)情況下,由 lambda 表達(dá)式捕獲的變量是常量,不能在 lambda 表達(dá)式體內(nèi)修改。如果你想要在 lambda 表達(dá)式中修改捕獲的變量,你可以將 lambda 表達(dá)式設(shè)為可變。可變lambda允許捕獲的變量被修改。這是通過在方括號 [ ] 中包含可變關(guān)鍵字來實(shí)現(xiàn)的。
例子:
lambda 表達(dá)式類似于普通函數(shù),但它們有一些關(guān)鍵的區(qū)別。例如,lambda 表達(dá)式的類型沒有被顯式指定,但可以由編譯器推斷出來。此外,lambda 表達(dá)式可以從周圍的作用域中捕獲變量,這使得它們非常適用于創(chuàng)建閉包和在 C++ 中使用函數(shù)式編程概念。
與傳統(tǒng)函數(shù)相比,lambda 表達(dá)式具有一些性能優(yōu)勢:
- 內(nèi)聯(lián)函數(shù):編譯器會自動將 lambda 表達(dá)式內(nèi)聯(lián),這意味著它們的代碼直接插入到調(diào)用函數(shù)中。這可以減少函數(shù)調(diào)用的開銷并提高性能。
- 避免命名函數(shù)的開銷:lambda 表達(dá)式?jīng)]有名稱,因此它們不必被聲明和存儲在符號表中,這可以減少開銷并提高性能。
- 改善高速緩存局部性:lambda 表達(dá)式可以在同一個函數(shù)中定義和使用,這意味著lambda使用的代碼和數(shù)據(jù)將存儲在與調(diào)用代碼相同的高速緩存行中。這可以改善高速緩存局部性并降低高速緩存失效的成本。
- 減小代碼大?。簂ambda 表達(dá)式通常比命名函數(shù)小,并且它們不需要外部函數(shù)調(diào)用,這可以減小編譯代碼的大小并提高性能。
- 增加靈活性:lambda 表達(dá)式可以用來將函數(shù)作為參數(shù)傳遞給其他函數(shù),這提供了更大的靈活性,可以改善性能,減少重復(fù)代碼的需求。
- 提高可讀性:lambda 表達(dá)式可以通過以緊湊而自包含的方式封裝復(fù)雜的邏輯來使代碼更易于閱讀。這可以通過使代碼更易于理解和維護(hù)來提高性能。
總之,與傳統(tǒng)函數(shù)相比,lambdas 可以通過減少開銷、提高緩存位置、減少代碼大小、提高靈活性和提高可讀性來提高性能。