c++特性:Lambda表达式

本文主要参考:
C++的lambda表达式
遇见C++ Lambda - Allen Lee - 博客园

Lambda表达式的基本语法,主要参考Lambda Expression Syntax:

  1. lambda-introducer(捕获字段)
  2. lambda-parameter-declaration-list(变量列表)
  3. mutable-specification(捕获的变量是否可以修改)
  4. exception-specification(异常设定)
  5. lambda-return-type-clause(返回类型)
  6. compound-statement(函数体)

捕获字段的说明

[] 表示捕获字段,表示不同,可以实现不同的捕获上文变量的效果。

[=]: = 表达按值访问。
[&]: & 表达引用访问。
下面是总结:

int main()
{
    int x , y, z;
    auto f1 = [] {};  //不捕获
    auto f2 = [=] {}; //按值访问所有上文所有变量(xyz)
    auto f3 = [&] {};  //引用访问所有上文变量
    auto f4 = [&x, y] {}; //引用访问x,按值访问y
    //等同于 [&x, =y]
    auto f5 = [&, z] {};//除了个别变量(z)按值访问
    /引用访问所有上文变量(xy)
    auto f6 = [=, &z] {};//除了个别变量(z)引用访问
    //按值访问所有上文变量
    // !!auto f7 = [&, x, &z] {};
    // 这样写非法,因为& 已经囊括引用捕获z了
    // 正确写法:
    auto f7 = [&, x] {};
}

示例代码

Lamdba表达式的产生一个匿名函数,由于类型无法确定,我们可以使用 auto 关键字进行声明:

#include<iostream>
//#include<vector>
//#include<algorithm>
//#include<functional>
//#include<typeinfo>
using namespace std;

int main()
{
    auto f = [] (int x, int y) ->int
    {
        cout<<"it works!"<<endl;
        return x+y;
    };
    cout<<"Now f is going to work!"<<endl;
    int z = f(4, 5);
    cout<<z<<endl;

    int add = [=]() -> int
    {
        cout<<"if works?"<<endl;
        return z;
    }();
    cout<<add<<endl;   
}

输出结果:

Now f is going to work!
it works!
9
if works?
9

注意,Lambda表达式只是产生一个匿名的函数,所以,如果只是这样声明:

    auto f = [] (int x, int y) ->int
    {
        cout<<"it works!"<<endl;
        return x+y;
    };

函数 f 是不会执行的。
正确的执行是:

f(4, 5);

我们可以从上面的输出结果中看到这个执行过程。(注意,最后int
add 是声明匿名函数后立刻执行的,分号前有括号”()” )

mutable的测试

#include<iostream>
using namespace std;

int main()
{
    int x = 4, y =5;
    int z = [=] () mutable ->int 
    {
        x++;  //如果没有 mutable关键字,编译不通过
             //但这句并不实际改变x的值
        return x+y;
    }();
    cout<<x<<endl;
    cout<<z<<endl;
}

输出结果:

4
10

经常的用法

Lambda确实方便了代码的编写。
下面通过一个例子说明。这个例子生成一个动态数组,然后随机填充改数组,接着输出数组中奇数的元素,并且统计奇数的个数。

#include<iostream>
#include<vector>
#include<algorithm>
#include<ctime>
using namespace std;

int main()
{
    srand(static_cast<int>(time(0)));
    vector<int> vc(20);
    generate(vc.begin(), vc.end(), []() -> int
    {
       return rand()%100;
    });
    int oddCount = 0;
    for_each(vc.begin(), vc.end(), [&oddCount](int x)
    {
        if(x%2==1)
        {
            ++oddCount;
            cout<<x<<endl;
        }
    });
    cout<<"The number of odd is: "<<oddCount<<endl;
}

输出的结果每次都不一样,其中一次:

31
9
45
61
69
1
29
35
65
77
57
3
99
The number of odd is: 13

一些问题

如何声明Lambda类型?
用auto关键字

什么时候捕获变量?
在写lambda的时候就捕获变量了,只是按照不同的方式,按值捕获的话,即使程序后面改变量依然更改,但是不影响捕获时的值。
引用捕获的话,则会持续影响。
代码示例:

#include<iostream>
using namespace std;

int main()
{   
    int x = 4, y = 5;
    auto f = 
    [x, &y]() -> int
    {
        return x+y;
    };
    x += 3;
    ++y;    
    int z = f();
    cout<<z<<endl;
}

输出:

10

–END–

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值