lambdas 就像是一個內聯函數,實際上編譯器會生成一個匿名的函數對象,或者說仿函數對象。
只要明確它是一個對象,重載了()操作符,接下來就很容易理解它的語法。
[函數對象參數] (操作符重載函數參數) mutable 或 exception 聲明 -> 返回值類型 {函數體}
1. 函數對象參數
就是定義仿函數類的成員變量
[] //未定義變量,在lambda內不能實用外部變量
[&] 使用的外部變量都按引用來捕獲
[=] 使用的外部變量都按值來捕獲
[a, &b] a按值捕獲,b按引用捕獲
[ &, a] a按值捕獲,其他按引用捕獲
[=, &a] a按引用捕獲,其他按值捕獲
2. 操作符重載函數參數
仿函數的參數,沒有的話可以不寫
3. mutable 或 exception
這倆不是必須的。
加上 mutable 可以修改傳遞進來的形參。
exception 用於函數拋出異常,例如,拋出整數異常,用 throw(int)。
4. -> 返回值類型
不是必須,可以省略。
5. {}
括號裏面防止函數體,具體的執行語句。
用法
// 第一種寫法,感覺很奇怪
[] {
cout << "hello" << endl;
}();//一個簡單的lambdas表達式
// 第二種寫法
auto lambda_func = [] {
cout << "hello" << endl;
};
lambda_func();
// 3.
int id = 0;
// 編譯器會生成一個匿名的函數對象 仿函數
auto f = [id]()mutable {// 沒有mutable id不能改變
cout << "id: " << id << endl;
++id;
};
id = 42;
f();
f();
f();
cout << id << endl;//42
// 4
auto f4 = [&id]() {//傳引用就不用mutable
cout << "4 id: " << id << endl;
++id;
};
f4();
Lambda常用於STL,簡化代碼,如下。
一個簡單的刪除器
vector<string> str = { "apple", "banana", "key", "cat", "dog", "orange", "banana" };
auto find_str = "banana";
auto sd = remove_if(str.begin(), str.end(), [find_str](string n) { return n == find_str; });
str.erase(sd, str.end());
str.erase(remove_if(str.begin(), str.end(),
[find_str](string n) { return n == find_str; }),
str.end());
vector<string>::iterator iter;
for (iter = str.begin(); iter != str.end(); ++iter)
{
cout << "刪除之後:"<<*iter<<" ";
}