lambda表达式
来源:互联网 发布:佳都数据服务有限公司 编辑:程序博客网 时间:2024/05/16 15:29
C++11引入了lambda表达式,使得程序员可以定义匿名函数,该函数是一次性执行的,既方便了编程,又能防止别人的访问。
如图,lambda表达式由下面几个部分构成:
1. lambda-introducer(捕获字段)
2. lambda-parameter-declaration-list(变量列表)
3. mutable-specification(捕获的变量可否修改)
4. exception-specification(异常设定)
5. lambda-return-type-clause(返回类型)
6. compound-statement(函数体)
外部变量的捕获规则
默认情况下,即捕获字段为 [] 时,lambda表达式是不能访问任何外部变量的,即表达式的函数体内无法访问当前作用域下的变量。
如果要设定表达式能够访问外部变量,可以在 [] 内写入” &”或者 “=” 加上变量名,其中” &”表示按引用访问,“=”表示按值访问,变量之间用逗号分隔,比如 [=factor, “&”total]表示按值访问变量 factor,而按引用访问 total。
不加变量名时表示设置默认捕获字段,外部变量将按照默认字段获取,后面在书写变量名时不加符号表示按默认字段设置,比如下面三条字段都是同一含义:
[&total, factor][&, factor][=, &total]
参数列表
lambda表达式的参数列表基本和函数的一致,不过有如下限制:
1. 参数列表不能有默认参数
2. 不能是可变参数列表
3. 所有的参数必须有个变量名
如果你不提供 mutable-specification,exception-specification,以及 lambda-return-type-clause,参数列表是也可以省略的。
如下面的表达式:
int main(){ int x = 4; int y = 5; int z = [=] { return x + y; }();}
能否修改捕获的变量
如果在参数列表后加上了 mutable,则表示表达式可以修改按值捕获的外部变量的拷贝。
异常设置
和函数一样,可以用 throw 来限定表达式能够抛出哪些异常。
返回类型
如果设置返回类型,你需要在类型名前面加上 ->。如果你只有一个返回语句的话,返回类型可以省略,编译器将会为你做出判断。
函数体
lambda表达式的函数体和普通函数大致相同。
将上图的代码片段补充完整:
int x = 10; int y = 3; int z ; z = [=]()mutable throw() -> int { int n = x + y; x = y ; y = n; return n;}(); cout<<z<<endl; cout<<"x:"<<x<<"\t"<<"y:"<<y<<endl;
运行结果为:
13x:10 y: 3
因为是以值传递的方式访问x,y所以x,y的值并没有发生改变
现在我们队lambda表达式的基本语法已经有一些了解,下面来举几个例子
首先这个例子说明如何向lambda表达式里面传递参数:
#include <iostream>using namespace std;int main(){ int n = [] (int x, int y) { return x + y; }(5, 4); cout << n << endl;}
运行结果为:9
通过这个例子我们可以看出,通过“函数体”后面的‘()’传入参数。
接下来这个例子可以看出,可以像调用函数一样使用lambda表达式,但是感觉这种方式和普通函数的定义与调用差不多,这里只是学习使用方式而已。
#include <iostream>using namespace std;int main(){ auto f = [] (int x, int y) { return x + y; }; cout << f(21, 12) << endl;}
运行结果为:33
Lambda表达式与STL算法一起使用,自己写测试代码的时候经常用到排序、输出数组什么的,通过下面列举的几个算法也比较方便:
#include <iostream>#include <algorithm>#include <ctime>using namespace std; int main(){ int a[10] = {0}; srand(time(NULL)); generate(a,a+10,[]()->int { return rand() % 100; }); cout<<"before sort: "<<endl; for_each(a, a+10, [&](int i){ cout<< i <<" "; }); cout<<endl; cout<<"After sort"<<endl; sort(a,a+10); for_each(a, a+10, [&](int i){ cout<< i <<" "; }); return 0;}
// generate();功能:用指定函数对象产生的值去给容器指定范围内元素赋值//for_each解释//Function for_each(InputIterator beg, InputIterator end, Function f) {// while(beg != end) // f(*beg++);//}
Lambda表达式的嵌套:#include <iostream>int main(){ using namespace std; int m = [](int x) { return [](int y) { return y * 2; }(x) + 3; }(5); cout << m << endl;}
运行结果:13
以上代码在VC10和VC11上都能顺利编译通过。
- Lambda Expressions(Lambda表达式)
- Lambda表达式
- Lambda表达式
- Lambda 表达式
- Lambda表达式
- lambda表达式
- lambda表达式
- Lambda表达式
- Lambda表达式
- Lambda表达式
- Lambda表达式
- Lambda 表达式
- Lambda表达式
- Lambda 表达式
- Lambda 表达式
- Lambda表达式
- Lambda表达式
- Lambda 表达式
- fdisk -l显示信息详解
- 【第四章】 资源 之 4.1 基础知识 ——跟我学spring3
- 愤怒的coder
- Amazon AWS 中国区 G2 服务器 配置运行
- 数据技术----大众点评
- lambda表达式
- ubuntu gedit中文乱码解决
- Android getWindow().setFlags方法
- UTF--->Unicode--->Ansi 这个最终返回的中文字符才是正确的,否则中文是乱码
- 图像分析:投影曲线的波峰查找
- OpenCV手势识别-手掌特征提取
- 开始刷leetcode day10:Merge Two Sorted Lists
- IOS开发我该如何学习?
- 【第四章】 资源 之 4.2 内置Resource实现 ——跟我学spring3