0.问题导向
使用C++ STL实现订单按照创建时间从小到大排查。
using Order = struct tagOrder{
unsigned int createTimspec;//创建时间戳
int id; //订单号
int totalPrice; //总价
int status; //订单状态
int payType; //支付类型
};
void orderSortByTime(vector<Order>& orders)
{
sort(orders.begin(),orders.end());
}
这样使用算法库的sort函数,编译报错:
error: no match for ‘operator<’ (operand types are ‘tagOrder’ and ‘tagOrder’)
43 | return *__it1 < *__it2; }.
编译器只默认支持对基本数据类型的大小比较,例如int,long等。自定义数据结构需要自定义比较函数。
using Order = struct tagOrder{
unsigned int createTimspec;//创建时间戳
int id; //订单号
int totalPrice; //总价
int status; //订单状态
int payType; //支付类型
};
int compare(Order a,Order b)
{
return a.createTimspec<b.createTimspec;
}
void orderSortByTime(vector<Order>& orders)
{
sort(orders.begin(),orders.end(),compare);
}
你发现没有,这个自定义的函数compare很简单,只有一行代码。但是每次调用仍然有函数调用的开销,如果系统中有大量的调用需求,那么函数调用对性能的影响就不能忽视了。
using Order = struct tagOrder{
unsigned int createTimspec;//创建时间戳
int id; //订单号
int totalPrice; //总价
int status; //订单状态
int payType; //支付类型
};
void orderSortByTime(vector<Order>& orders)
{
sort(orders.begin(),orders.end(),[](Order a,Order b){return a.createTimspec<b.createTimspec;});
}
按照上图方法也可以实现订单排序功能,sort函数的第三个参数替代了自定义的compare函数,"[](Order a,Order b){return a.createTimspec<b.createTimspec;}",这串就是我们今天要学习的Lambda表达式。
1.Lambda表达式简介
Lambda表达式,也称为Lambada函数,实际是一个匿名函数(不需要定义函数名),主要的使用场景是函数入参,例如算法函数和异步函数。在C++中,从C++11开始引入Lambda表达式,之后在后面的C++14、C++17、C++20、C++23版本对Lambda表达式都有更新和扩展。这里我们选择最初的C++11版本,学习下Lambda表达式的基本语法和用法。
2.Lambda表达式语法
Lambda基本语法如下,包含捕获、参数、修饰符、返回类型和实体五部分。其中,修饰符和返回类型是可选部分。下面结合例子学习这五部分组成。
[capture](parameters) modifiers -> return-type {body}
3.Captures
1>捕获引用类型和值类型
int arg=10;
auto lambdaCap = [&arg] (){arg++;};//capture by reference
lambdaCap();
cout<<"arg="<<arg<<endl;//arg=11
return 0;
上图是捕获引用类型,不用解释。
int arg=10;
auto lambdaCap = [arg](){arg++;};//capture by value
lambdaCap();
cout<<"arg="<<arg<<endl;
//编译失败
main.cpp:265:30: error: increment of read-only variable ‘arg’
上图编译失败。
int arg=10;
auto lambdaCap = [arg]()mutable{arg++;};//capture by value
lambdaCap();
cout<<"arg="<<arg<<endl;//arg=10
增加mutable修饰符后编译通过,修饰符后面介绍。
2>捕获有效范围内的所有变量
int arg=10;
auto lambdaCap = [=]()mutable{arg++;};//capture by value
lambdaCap();
cout<<"arg="<<arg<<endl;//arg=10
上图是使用'='表示以值类型的方式捕获有效范围内的所有变量。
int arg=10;
auto lambdaCap = [&]()mutable{arg++;};//capture by value
lambdaCap();
cout<<"arg="<<arg<<endl;//arg=11
上图是使用'&'表示以引用的方式捕获有效范围内的所有变量。
4.Parameters
auto lambdaAdd = [](int a,int b){return a+b;};
cout<<"sum="<<lambdaAdd(1,2)<<endl;//sum=3
这里的参数和函数的入参类似,入参也可以有默认值。
auto lambdaAdd = [](int a,int b=1){return a+b;};//capture by value
cout<<"sum="<<lambdaAdd(1)<<endl;//sum=2
5.Body
实体部分类似普通函数的函数体,例如开端的订单排序例子中的Body返回创建时间的大小。
void orderSortByTime(vector<Order>& orders)
{
sort(orders.begin(),orders.end(),[](Order a,Order b){return a.createTimspec<b.createTimspec;});
}
6.Modifiers
可选部分,可以通过修饰符设置Lambda匿名函数的属性,例如在Captures部分我们用的mutable修饰符。还有noexcept、noreturn等。
int arg=10;
auto lambdaCap = [arg]()mutable{arg++;};//capture by value
lambdaCap();
cout<<"arg="<<arg<<endl;//arg=10
7.Return-Type
可选部分,如果不设置返回类型,则由编译器根据代码逻辑自动判断类型,例如上面的所有例子都是这样。如果设置返回类型,则强制要求编译器按照该类型返回。
auto lambdaAdd = [](int a,int b)->long{return (long)a+b;};
cout<<"sum="<<lambdaAdd(0x7FFFFFFF,0x1)<<endl;//sum=2147483648
8.总结
这里只是简单介绍了Lambda函数的产生以及基本的语法和使用场景,还有很多深奥的相关部分需要持续学习。日拱一卒无有尽,终不唐捐入海流。
标签:int,lambdaCap,Order,匿名,初识,arg,orders,Lambda From: https://www.cnblogs.com/madadam/p/18405336