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上都能顺利编译通过。



0 0
原创粉丝点击