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<<" ";
}