行业知识
【C++】C++11中
C++11中
- 1.lambda表达式
- 2.可变参数模板
- 3.包装器
1.lambda表达式
在前面���们学习过仿函数。仿函数的作用到底是干什么的呢?
它为了抛弃函数指针!
主要是因为函数指针太难学了
就比如下面这个,看着也挺难受的。
它的参数是一个函数指针,返回值也是一个函数指针!
就如在C++98中,如果想要对一个数据集合中的元素进行排序,可以使用std::sort方法。也可以提供一个仿函数用来控制排序方式非常舒服
#include #include int main(){int array[] = { 4,1,8,5,3,7,0,9,2,6 };// 默认按照小于比较,排出来结果是升序std::sort(array, array + sizeof(array) / sizeof(array[0]));// 如果需要降序,需要改变元素的比较规则std::sort(array, array + sizeof(array) / sizeof(array[0]), greater());return 0;}注意:
模板传仿函数,传仿函数类型
函数传仿函数,传仿函数对象
仿函数默认小于升序,可以自己写一个大于降序的 【内部是cmp(v[i+1],v[i])比较】
就比如把下面的对象如果按照评价,价格排序,要是重载()进行排序就需要写两个仿函数。如果在按照别的排序还需要重新再写一个对应的仿函数,这样写太麻烦了。而且仿函数名字取不好,就更麻烦了!
struct Goods{string _name; // 名字double _price; // 价格int _evaluate; // 评价 // ...Goods(const char* str, double price, int evaluate):_name(str), _price(price), _evaluate(evaluate){}};struct ComparePriceLess{bool operator()(const Goods& gl, const Goods& gr){return gl._price gr._price;}};int main(){vector v = { { "苹果", 2.1, 5 }, { "香蕉", 3, 4 }, { "橙子", 2.2, 3 }, { "菠萝", 1.5, 4 } };// 评价、价格sort(v.begin(), v.end(), ComparePriceLess());sort(v.begin(), v.end(), ComparePriceGreater());return 0;}但如果是下面这样写个lambda表达式,就很清晰
int main(){vector v = { { "苹果", 2.1, 5 }, { "香蕉", 3, 4 }, { "橙子", 2.2, 3 }, { "菠萝", 1.5, 4 } };// 评价、价格//sort(v.begin(), v.end(), ComparePriceLess());//sort(v.begin(), v.end(), ComparePriceGreater());//sort传一个可调用的匿名对象sort(v.begin(), v.end(), [](const Goods& gl, const Goods& gr) {return gl._price gl._price; });//价格降序return 0;}lambda表达式语法
lambda表达式书写格式:[capture-list] (parameters) mutable -> return-type { statement }
lambda表达式各部分说明
-
[capture-list] : 捕捉列表,该列表总是出现在lambda函数的开始位置,编译器根据[]来判断接下来的代码是否为lambda函数,捕捉列表能够捕捉上下文中的变量供lambda函数使用。
-
(parameters):参数列表。与普通函数的参数列表一致,如果不需要参数传递,则可以连同()一起省略
-
mutable:默认情况下,lambda函数总是一个const函数,mutable可以取消其常量性。使用该修饰符时,参数列表不可省略(即使参数为空)。
-
->returntype:返回值类型。用追踪返回类型形式声明函数的返回值类型,没有返回值时此部分可省略。返回值类型明确情况下,也可省略,由编译器对返回类型进行推导。
-
{statement}:函数体。在该函数体内,除了可以使用其参数外,还可以使用所有捕获到的变量。
[capture-list] : 捕捉列表 必须要写用来判断是否是一个lambda表达式
(parameters):参数列表 有参数就写没参数就不写
mutable 是一个修饰符一般都不需要
->returntype:返回值类型 一般都不写,编译器自动推导
{statement}:函数体 必须要写
注意:
在lambda函数定义中,参数列表和返回值类型都是可选部分,而捕捉列表和函数体可以为空。因此C++11中最简单的lambda函数为:[]{}; 该lambda函数不能做任何事情。
lambda表达式实际是一个的可以调用的匿名函数对象!
int main(){//写一个进行int对象比较的lambda//[](int x, int y)->bool {return x > y; };//指定返回值类型[](int x, int y) {return x > y; };return 0;}没有名字写完怎么调用呢?
int main(){//写一个进行int对象比较的lambda//auto compare = [](int x, int y)->bool {return x > y; };//指定返回值类型auto compare = [](int x, int y) {return x > y; };cout int a = 0, b = 1;auto add1 = [](int x, int y) { return x + y; };cout return x + b; };cout int a = 0, b = 1;auto add1 = [](int x, int y) { return x + y; };cout return x + b; };cout int a = 0, b = 1;auto add1 = [](int x, int y) { return x + y; };cout return x + b; };cout int tmp = a;a = b;b = tmp;};return 0;}//多捕捉auto swap = [a, b]()mutable{int tmp = a;a = b;b = tmp;};swap();cout int a = 0, b = 1;//以引用方式捕捉auto swap = [&a, &b](){int tmp = a;a = b;b = tmp;};swap();cout int a = 0, b = 1;auto swap = [=](){//这对括号外面的一层就是父作用域int tmp = a;a = b;b = tmp;};swap();cout int a = 0, b = 1;auto swap = [&](){//这对括号外面的一层就是父作用域int tmp = a;a = b;b = tmp;};swap();cout int x = 0, y = 1;auto func2 = [=, &y](){cout for (; x -
上一篇:云服务器怎么部署人员?