Lambda表達式在c++++中是一種簡潔定義匿名函數對象的方式,常用于需要簡單函數邏輯的地方。它的語法形式為capture -> return_type { function_body },其中capture指定捕獲外部變量的方式,parameters是參數列表,return_type可省略由編譯器推導,function_body為函數體。常見用法包括:1. 配合stl算法如std::sort使用;2. 作為回調函數;3. 替代輕量級functor。捕獲列表可根據需求選擇[=]按值捕獲所有變量,[&]按引用捕獲,或指定捕獲特定變量如[var]、[&var]、[this]。返回類型通常可自動推導,但若存在多個不一致的return語句則需顯式聲明以避免歧義。例如lambda表達式在排序時可替代比較函數,捕獲變量時需根據是否希望反映外部變化選擇值或引用捕獲,且注意生命周期問題,確保代碼安全與效率。
Lambda表達式在c++中是一種簡潔定義匿名函數對象的方式,常用于需要簡單函數邏輯的地方,比如作為參數傳給算法函數(如std::sort、std::for_each)或者事件回調等。
它的語法形式大致如下:
[capture](parameters) -> return_type { function_body }
其中:
立即學習“C++免費學習筆記(深入)”;
- capture:捕獲外部變量的方式,可以是值捕獲(=)、引用捕獲(&)或指定捕獲某些變量。
- parameters:參數列表,和普通函數的參數寫法一樣。
- return_type:返回類型可省略,編譯器會自動推導。
- function_body:函數體內容。
基本用法:替代簡單的函數對象
比如排序一個數組,你想按降序排,但不想專門寫個比較函數。這時候可以用lambda:
std::vector<int> nums = {3, 1, 4, 2}; std::sort(nums.begin(), nums.end(), [](int a, int b) { return a > b; });
這里 lambda 表達式 [](int a, int b) { return a > b; } 就充當了比較函數的作用。
常見使用場景包括:
- 配合STL算法使用,如find_if、transform等。
- 作為回調函數傳遞給其他模塊。
- 在需要輕量級函數對象時替代functor。
捕獲列表怎么選?看你要不要用外部變量
lambda 的一大特點是能“捕獲”它所在作用域中的變量。捕獲方式有幾種,常見的有:
- [=]:以值的方式捕獲所有外部變量。
- [&]:以引用的方式捕獲所有外部變量。
- [var]:只捕獲特定變量,按值。
- [&var]:只捕獲特定變量,按引用。
- [this]:捕獲當前類的this指針,用于訪問成員變量。
舉個例子:
int x = 10; auto f = [x](int y) { return x + y; }; std::cout << f(5); // 輸出15
這個lambda捕獲了x的值,之后即使x變了,f里的x還是原來的10。
如果你希望它能修改x,就得用引用捕獲:
int x = 10; auto f = [&x](int y) { return x + y; }; x = 20; std::cout << f(5); // 輸出25
所以什么時候用值捕獲,什么時候用引用,要看你是否希望lambda內部反映外部變量的變化。
返回類型可以省略,但有時得顯式寫出來
大多數情況下,lambda的返回類型可以由編譯器自動推導,不需要寫-> return_type這部分。
但如果函數體內有多個return語句,且返回類型不一致,就需要明確寫出返回類型,否則編譯器可能無法推導。
例如:
auto func = [](bool flag) -> int { if (flag) return 1; else return 0.5; // 這里會轉換成int };
雖然返回的實際上是double,但因為返回類型指定為int,結果會被轉換。
這種時候明確返回類型是為了避免歧義或隱式轉換帶來的問題。
基本上就這些。lambda表達式在C++11引入后非常常用,掌握好捕獲方式和基本結構,就能寫出更簡潔清晰的代碼。不過也要注意別濫用,比如捕獲this時要小心生命周期問題,否則容易出現懸空引用。