很多语言都有lambda, c++自然不能缺, 在c++11里面加入了, 是程序猿喜欢的语法糖, 便于阅读, 也便于理解. 当然, 它有很多相关概念, 这里尽可能展开说.
你会觉得和函数声明很像, 但是注意, 不可以有默认值, 也不支持可变参数, 类似printf, 参数必须要有参数名. 甚至你会觉得和python3很像, 尤其是这个->return type, 所以你看, c++也越来越友好了.
先来几个小栗子:
可以看到a, b是形参, 1, 5是实参, f似乎是函数, 这个放到后面说.
然后你发现, lambda更神奇的地方在于, 可以捕获外界参数, 是不是很酷, 其实这里本质还是值传递, 当然后面有引用, 但是默认是值传递.
捕获形式 | 说明 |
---|---|
[] | 不捕获任何外部变量 |
[var1,var2, …] | 默认以值得形式捕获指定的多个外部变量(用逗号分隔) |
[this] | 以值的形式捕获this指针 |
[=] | 以值的形式捕获所有外部变量 |
[&] | 以引用形式捕获所有外部变量 |
[=, &var1] | 变量var1以引用形式捕获,其余变量以传值形式捕获 |
[&, var1] | 变量var1以值的形式捕获,其余变量以引用形式捕获 |
很多都是一眼懂, 举个栗子吧:
x是值传递, y, z是引用传递, 值传递实际上是不能修改的, 但是这里加了mutable, 所以可以在函数体内进行改动. 然后引用传入, 会对外部产生影响, 值传入则不会, 很好理解.
甚至可以传入this指针.
传入this指针之后, 就可以使用成员变量.
然后你会发现一个问题, 我这里写的都是auto, 那具体是什么呢?
返回一开始的栗子, 看到function里面写了函数的返回值, 然后括号里面是参数类型. std::function是一个可调用对象包装器,是一个类模板,可以容纳除了类成员函数指针之外的所有可调用对象,它可以用统一的方式处理函数、函数对象、函数指针,并允许保存和延迟它们的执行。 目的肯定是取代函数指针的, 来看一个栗子:
想想之前的写法, 是不是用宏定义一个函数指针, 类似
typedef int(*fp)(int, int);
, 是不是很像, 用function的话, 整体也更直观好操作.
曾经我被问到, 如何实现lambda获取外部参数的功能, 那答案就是利用bind, 先来看个栗子:
是不是挺酷的, 什么都没改, 就把参数位置换了.
之前也说了, lambda是不支持默认参数的, 但是通过bind+占位符, 就很好实现了这个点, 甚至可以随意调整参数位置. 而且可以绑定成员函数, 不过你需要传入具体实例在第二个参数.
最后对比下bind和lambda, 当然二者是可以配合使用的, 怎么用还是看自己. 我的话, 怎么简洁怎么用. ref简单说下, 主要是有些变量不支持值传递, bind这里就要写成ref(os).
真的是很实用的点, 让c++灵活了很多. 就像设计了while之后, 又设计了for, 设计了for之后又设计了for_each, 语言都是不断发展的, 学习新的真的很有必要.