C++ Lambda表达式

lambda表达式的完整声明如下:

[capture list](params list) mutable exception -> return type{function body}
 
//capture list : 捕获列表  //[var]:以值的形式捕获,[&]:引用方式捕获,[=]:值捕获
//params list : 参数列表
//mutable : 捕获列表可以修改
//exception : 异常处理
//return type : 返回值类型
#include<iostream>
using namespace std;
 
int main()
{
    int a = 9;
    auto fun1 = [=]()mutable{return ++a;};
    cout<<fun1()<<endl; //10
    cout<<a<<endl; //9
    return 0;
}

以值传递,在lambda表达式中,修改a的值后,main()中a的值并未改变。说明传进去的a是一个副本。这也普通函数的参数传递中的值传递是一样。但是,普通函数按值传递,可以对得到的形参进行任意改变,如:++param,–param等,lambda表达式可以任意改变按值传递的参数的值比较特殊。

例子如下:

#include<iostream>
using namespace std;
 
int main()
{
    int a = 9;
    auto fun1 = [=]{return a+1;}; //lambda表达式第一次初始化,a将被视为常量,保持不变。
    auto fun2 = [&]{return a+1;};

    cout<<"fun1:"<<fun1()<<endl; //10
    cout<<"fun2:"<<fun2()<<endl; //10
    ++a;
    cout<<"++a执行之后的值"<<endl;
    cout<<"fun1:"<<fun1()<<endl; //9 + 1 = 10
    cout<<"fun2:"<<fun2()<<endl; //10 + 1 = 11
 
    return 0;
}

lambda表达式中,a被视为常量。初始化一次后,保持不变。相反的,如果需要捕捉的值成为Lambda函数运行时的变量,则应该采用按引用方式进行捕捉。

再看一道例子:

#include<iostream>
using namespace std;
 
int main()
{
    int a = 9;
    auto fun1 = [=]{return ++a;}; //代码片段1
    auto fun2 = [&]{return ++a;}; //代码片段2
    auto fun3 = [=]()mutable{return ++a;}; //代码片段3
    return 0;
}

若运行程序,会有什么问题?

代码片段1:编译报错,error: increment of read-only variable ‘a’

代码片段2:正确运行

代码片段3:正确运行

默认情况下,Lambda函数总是一个const函数,mutable可以取消其常量性。按照规定,一个const的成员函数是不能在函数体内修改非静态成员变量的值。

总结:

1.若按值传递,表达式内部复制了一份捕获的变量;不论被捕获的变量如何改变(如++a),其已被捕获的值,在表达式内部保持不变;

2.若按引用传递,表达式内部的值,使用的就是被捕捉的变量的值;所以,被捕获的变量改变时,其内部的值也会改变;

3.按值传递,若想修改变量的值,则需要加mutable关键字;因为lambda默认是常函数;在一个常函数内部,只能修改static类型变量的值,不能修改非static类型变量的值。

转自:https://blog.csdn.net/zuo_yong/article/details/84565385

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值