C++lambda
liufeng2023 人气:0lambda表达式
- C++11 函数对象的升级版 =》 lambda表达式
- 函数对象的缺点:(需要定义一个类)
- 函数对象使用在 泛型算法参数传递 比较性质/自定义操作 优先级队列 智能指针(自定义智能指针的删除器)
lambda表达式原理: 就是函数对象更高级的实现!
1、lambda表达式语法
例1:
lambda表达式对应函数对象小括号重载函数的。
- []为空,相当于构造函数不接收任何外部传进来的变量。
- ()是运算符重载函数,具体接收的参数的个数
- 然后是返回值,看是无类型还是其他类型。
- 最后是函数代码
[]不为空,相当于构造函数接收任何外部传进来的变量a,b。
例2:
如果lambda表达式的返回值不需要,那么"->返回值"可以省略的
[捕获外部变量]
[]:表示不捕获任何外部变量
[=]:以传值的方式捕获外部的所有变量
[&]:以传引用的方式捕获外部的所有变量
[this]:捕获外部的this指针
[=,&a]:以传值的方式捕获外部的所有变量,但是a变量以传引用的方式捕获
[a, b]:以值传递的方式捕获外部变量a和b
[a, &b]:a以值传递捕获,b以传引用的方式捕获
值传递:
加上mutable,表示将值传递的形参a,b改掉;不影响外部的实参。
引用传递:
修改的是实参,不需要加mutable
2、lambda应用
例1—从大到小排序
例2—按序插入元素65
例3—for_each
#include <iostream> #include <algorithm> #include <vector> using namespace std; int main() { vector<int> vec; for (int i = 0; i < 20; i++) { vec.push_back(rand() % 100 + 1); } sort(vec.begin(), vec.end(), [](int a, int b)->bool { return a > b; }); for (int val : vec) { cout << val << " "; } cout << endl; //65按序插入序列 要找第一个小于65的数字 auto it = find_if(vec.begin(), vec.end(), [](int a)->bool {return a < 65; }); if (it != vec.end()) { vec.insert(it, 65); } for (int val : vec) { cout << val << " "; } cout << endl; for_each(vec.begin(), vec.end(), [](int a) { if (a % 2 == 0) cout << a << " "; }); cout << endl; return 0; }
3、lambda表达式的应用实践
既然lambda表达式只能使用在语句当中,如果想跨语句使用之前定义好的lambda表达式,怎么办?用什么类型来表示lambda表达式?
- lambda表达式 =》 函数对象 用function类型绑定它
- 用function类型表示函数对象的类型
- bind绑定器绑定的结果依然还是一个函数对象;
1、计算器案例
2、智能指针案例
3、优先级队列
上面写法灵活性太差。现在优化:
priority_queue本身就有3个模板参数,分别是元素类型、容器类型、函数对象。
可以接收外部自定义的函数对象:
#include <iostream> #include <functional> #include <queue> using namespace std; class Data { public: Data(int val1 = 10, int val2 = 10) :ma(val1), mb(val2) {} int ma; int mb; }; int main() { //优先级队列 //priority_queue<Data> queue; using FUNC = function<bool(Data&, Data&)>; priority_queue<Data, vector<Data>, FUNC> maxHeap([](Data& d1, Data& d2)->bool { return d1.mb > d2.mb; }); maxHeap.push(Data(10, 20)); maxHeap.push(Data(15, 15)); maxHeap.push(Data(20, 10)); return 0; }
加载全部内容