1.lambda表达式
a.出现由来:
以sort为例,我们可以传入一个仿函数对自定义类型进行排序。但是,对每一种比较方式我们都要显示传一个仿函数太麻烦。要是乱命名更加要命,那就除了写这段代码的人没人看得懂了!
b.lambda表达式的格式:
[]()->{} :[]是捕捉列表
:()是参数列表
:->返回值类型
:{}函数体
c.->返回值基本可以省去,可以自动推导。
d.可以写无参数的lambda表达式,捕捉列表可以捕捉当前父作用域(当前栈帧)的所有变量。
例:
#include<iostream>
using namespace std;
int main()
{
int a = 10; int b = 20;
auto swap = [&a, &b]() {int temp; temp = a; a = b; b = temp; };
//用&才可以传引用改变值
swap();
cout << a <<" "<< b << endl;
return 0;
}
e.对于无参数的lambda表达式
“=”表示将所有变量传值传入,“&”表示传地址,同时可以混用,例:
#include<iostream>
using namespace std;
int main()
{
int a = 10; int b = 20; int c = 30; int d = 40;
auto fun = [=, &d]()
{
cout << a << endl;
cout << b << endl;
cout << c << endl;
d = 50;
cout << d << endl;
};
fun();
return 0;
}
f.lambda表达式底层和仿函数完全一致
2.包装器(function)
顾名思义,包装器使用来将不同的函数指针或者lambda亦或者成员函数打包分类。
上一个例题看看使用场景:
题名:力扣(150. 逆波兰表达式求值)想看看的戳这里
class Solution {
public:
int evalRPN(vector<string>& tokens) {
stack<long long> st;
//不用function得搞一大堆判断
map<string,function<long long(long long,long long)>> mp=
{
{"+",[](long long a,long long b){return a+b;}},
{"-",[](long long a,long long b){return a-b;}},
{"*",[](long long a,long long b){return a*b;}},
{"/",[](long long a,long long b){return a/b;}}
};
for(auto& e:tokens)
{
if(mp.count(e))
{
//先取出的是右边的值
long long right=st.top();
st.pop();
//再取出的是左边的值
long long left=st.top();
st.pop();
//将出栈的两个数运算一下,再将结果存入栈当下一次运算的左值。
long long ret=mp[e](left,right);
st.push(ret);
}
else
{
st.push(stoll(e));
}
}
//剩下的那个值就是结果
return st.top();
}
};
3.bind的用法
bind在我看来就是为了将特定的函数参数固定。以对类的成员函数包装为例子,因为成员函数必须要实力对象才能调用,所以在不用bind的前提下,我们必须显示传一个匿名对象来调用该函数。
class Sub
{
public:
int sub(int a, int b)
{
return a - b;
}
};
int main()
{
function<int(int, int)> funcSub = bind(&Sub::sub, Sub()//直接传一个匿名对象, _1, _2);
int ret = funcSub(20, 5);
cout << ret << endl;
}