C++中的Lamda表达式是什么?

在使用c++标准库时,往往会写一些东西来声明意图,如果自己不写就会使用默认版本。函数对象/仿函数可以用lambda的形式来写。

C++ 11 introduced lambdas, allowing the definition of inline functionality, which can be used as a parameter or a local object. Lambdas change the way the C++ standard library is used.

A lambda is a definition of functionality that can be defined inside statements and expressions. Thus, you can use a lambda as an inline function. The minimal lambda function has no parameters ans simply does something.

简化写法

//这一段只是一个对象,相当于一个类型
[]{
    std::cout << "hello lambda" << std::endl;
}
//这一段只是一个对象
[]{
    std::cout << "hello lambda" << std::endl;
}()  //加了括号之后就表示直接调用 输出"hello lambda"
//基本不会这么写,因为只能调用一次,不如直接写大括号里的内容
//这一段只是一个对象
auto L = []{
    std::cout << "hello lambda" << std::endl;
}
...
L();  //调用L,输出"hello lambda"

完整形式

[…导入器](…参数) m u t a b l e o p t mutable_{opt} mutableopt t h r o w S p e c o p t throwSpec_{opt} throwSpecopt -> r e t T y p e o p t retType_{opt} retTypeopt{…}

  • 可选参数:
    m u t a b l e o p t mutable_{opt} mutableopt: 导入器中的内容是否可以被改写
    t h r o w S p e c o p t throwSpec_{opt} throwSpecopt :这个函数是否可以扔出异常
    r e t T y p e o p t retType_{opt} retTypeopt:返回类型
    这三个参数可以都不写,但只要有一个存在,就一定要写前面的小括号;如果三个参数都没有,小括号可写可不写。

  • 导入器
    取用从外部传进来的参数,可传值或传引用。
    1)[]中不加特殊符号就是传值
    2)如果是[&b]这种形式表示传引用。
    3)[=,&y]表示y是传引用,其他参数都是传值(=在此是默认写法)
    举例:下图左右两边是基本等效的(mutable没有体现出来),注意四次id的值。由于是传值,所以不再会受到后来id=42的影响。如果没有mutable,就不可以++id了。
    在这里插入图片描述下面三种形式的比较:
    在这里插入图片描述
    举例:1和2形式等效
    在这里插入图片描述

  • 举例:用lambda函数写一个set的排序准则。
    用lambda的变量类型,我们一般都用auto表示。当需要用这个类型作为参数时,使用decltype。在下图中,就可以把这个类型值传到set的带参数的构造函数中去了。
    lambda函数比较奇特,没有默认构造函数,也没有赋值操作。 所以,如果写成std::set<Person, decltype(cmp)> coll就会报错,必须要把coll(cmp)加上。
    在这里插入图片描述所以,对于一个排序准则,写成class会更加直观一些。

  • 举例:删除在30到100之间的数字,左边为lambda的写法,右边是functor的写法在这里插入图片描述左边写成了内联函数的形式,效率可能会快一点,但侯捷老师也指出,效率主要还是要看算法上,这里的提升是很有限的。

编程举例

@力扣973.最接近原点的K个点

lambda表达式有时候会被用在写自定义的排序函数中:

class Solution {
public:
    vector<vector<int>> kClosest(vector<vector<int>>& points, int k) {
        sort(points.begin(), points.end(), [](const vector<int>& u, const vector<int>& v) {
            return u[0] * u[0] + u[1] * u[1] < v[0] * v[0] + v[1] * v[1];
        });
        return {points.begin(), points.begin() + k};
    }
};

当然,也可以不用lambda表达式的形式:

static bool cmp(const vector<int>& u, const vector<int>& v){
	return u[0]*u[0]+u[1]+u[1] < v[0]*v[0] + v[1]*v[1];
}

其他讨论:
在类中=捕捉的是this对象:https://leetcode-cn.com/circle/discuss/fO4fEy/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值