a.出现由来:
以sort为例,我们可以传入一个仿函数对自定义类型进行排序。但是,对每一种比较方式我们都要显示传一个仿函数太麻烦。要是乱命名更加要命,那就除了写这段代码的人没人看得懂了!
b.lambda表达式的格式:
[]()->{} :[]是捕捉列表
:()是参数列表
:->返回值类型
:{}函数体
c.->返回值基本可以省去,可以自动推导。
d.可以写无参数的lambda表达式,捕捉列表可以捕捉当前父作用域(当前栈帧)的所有变量。
例:
#includeusing 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表达式
“=”表示将所有变量传值传入,“&”表示传地址,同时可以混用,例:
#includeusing 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表达式底层和仿函数完全一致
顾名思义,包装器使用来将不同的函数指针或者lambda亦或者成员函数打包分类。
上一个例题看看使用场景:
题名:力扣(150. 逆波兰表达式求值)想看看的戳这里
class Solution {
public:int evalRPN(vector& tokens) {stack st;//不用function得搞一大堆判断map> 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();}
};
bind在我看来就是为了将特定的函数参数固定。以对类的成员函数包装为例子,因为成员函数必须要实力对象才能调用,所以在不用bind的前提下,我们必须显示传一个匿名对象来调用该函数。
class Sub
{
public:int sub(int a, int b){return a - b;}
};
int main()
{function funcSub = bind(&Sub::sub, Sub()//直接传一个匿名对象, _1, _2);int ret = funcSub(20, 5);cout << ret << endl;
}