lambda表達式的語法如下所示:
[capture_block](parameters) exceptions_specification -> return_type {body}
[捕捉塊](參數) 異常 -> 返回值類型 {主體}
或者更直白地看如下:
??這里假設我們定義了一個如上圖的lambda表達式。現在來介紹途中標有編號的各個部分是什么意思。
1. Lambda表達式的引入標志,在‘[]’里面可以填入‘=’或‘&’表示該lambda表達式“捕獲”(lambda表達式在一定的scope可以訪問的數據)的數據時以什么方式捕獲的,‘&’表示一引用的方式;‘=’表明以值傳遞的方式捕獲,除非專門指出。
2. Lambda表達式的參數列表
3. Mutable 標識
4. 異常標識
5. 返回值類型
6.“函數”體,也就是lambda表達式需要進行的實際操作
下面的例子將逐步演示如何使用lambda表達式:
范例一:無參數的lambda表達式
[]{std::cout<<"Hello from Lambda!"<<std::endl;}();
or
[](){std::cout << "Hello from Lambda!" << std::endl; }();
輸出如下所示:
Hello from Lambda在控制臺輸出Hello from Lambda,尾部的括號使該表達式可立即執行。
范例二:帶參數的lambda表達式
string str = [](const string& str)->string{return "Hello from " + str; }("second lambda");
cout << str << endl;
輸出如下所示:
Hello from second Lambda該lambda表達式接受一個string參數并返回一個string,結果保存在變量result中,尾部的括號使得該表達式立即執行。
范例三:像平常的調用函數一樣使用lamdba表達式
auto f = [](std::string str)->string{return "hello from " + str; };auto f2 = [](std::string str) {return "hello from " + str; };cout << f2("third lambda") << endl;
輸出如下所示:
? ? ?hello from third lambda
此處保存指向lambda表達式的指針,并且通過函數指針執行該表達式。范例四:(STL與lambda)
#include <iostream>
#include <algorithm>
#include <vector>auto main(int argc, char** argv) -> int
{
std::vector<int> vec={1, 2, 3, 4, 5, 6, 7, 8, 9};
int value=3;
int cnt=std::count_if(vec.cbegin(), vec.cend(), [=](int i){return i>value;});
std::cout<<"Found "<<cnt<<" values > "<<value<<std::endl;return 0;
}
輸出如下所示:
Found 6 values > 3
通過count_if算法計算vector中滿足特定條件的元素個數,lambda表達式的形式給出了條件,注意表達式中的=,等號表示通過值捕捉所在作用域的變量,這個例子中捕捉的是value的值。前面的例子[]為空,即捕捉塊為空,那么在lambda表達式的主體body內就無法訪問變量了。以下是關于捕捉塊的詳細介紹:
[=] ? 通過值捕捉所有變量[&] ?通過引用捕捉所有變量
[value] 通過值捕捉value,不捕捉其它變量
[&value] 通過引用捕捉value,不捕捉其它變量
[=, &value] 默認通過值捕捉,變量value例外,通過引用捕捉
[&, value] 默認通過引用捕捉,變量value例外,通過值捕捉
范例五:(STL與lambda結合)
#include <iostream>
#include <algorithm>
#include <vector>auto main(int argc, char** argv) -> int
{
std::vector<int> vec2 = { 11, 22, 33, 44 };
int index = 0;
for_each(vec2.begin(), vec2.end(),?[index](int i){std::cout << "Value " << (index++)?<< ": " << i << std::endl; });
return 0;
}
注意:這里必須使用[&index],而不能使用[index],原因在于index++;否則會出現
錯誤提示:不能在非可變 lambda 中修改按值捕獲
通過for_each算法可以對給定范圍中的所有元素執行特定操作,調用lambda表達式,并將這個值作為參數傳遞給lambda表達式。
范例六:(多個參數)
int n = [](int x, int y) { return x + y; }(5, 4);cout << n << endl;
從以上示例來看,
1.如果我們想要提示返回的類型,就要加上->return_type {},否則,直接使用{}即可。
2.C++ 11的lamdba表達式來源于其它語言,像Python,也有lamdba表達式。如:lambda x: x * x
范例程序差不多了,在C++11中,官方似乎一直鼓勵大家用lambda表達式,而不是函數對象,lambda表達式更易于使用和理解。