lambda表达式

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;

运行结果为:

13

x: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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值