今天学习了C++11引入的Lambda表达式,Lambda在使用上有很多的方便之处。我们可以将之用于函数的回调,操作的封装的等地方。如果我们有Objective-c的经验的话,其实我可以将Lambda表达式和Block进行对比学习,两者有很多的相似之处。
优势
根据对Lambda的了解,发现其用途和函数指针有太多的相似之处,甚至可以理解为功能重叠。那么为什么在C++11中还要引入Lambda表达式呢?
1. 函数指针是类型不安全的
C语言的函数指针就是一个地址变量,在赋值和调用的时候没有任何类型检查。任何一种函数指针都可以转型为其他类型的函数指针, 当转型回来时,与原函数指针相同。必须由开发者自己保证正确的类型。函数指针无法提前在编译器给出错误提示。
2. bind能保证类型安全,但对于绑定变量的内容,需要程序员保证有效性
综合上述原因,引入Lambda表达式还是很有必要的
Lambda表达式
我们将从Lambda表达式的定义,调用,传递几个方面进行阐述
Lambda表达式的定义
Lambda表达式的定义我们可以根据下图给出准确描述
- 表示要捕获的作用域内的变量
· 为空时表示不捕获任何变量
· =表示按值传递的捕获,表示捕获作用域内所有的变量
· 直接输入变量名,表示指定捕获特定的变量
· &变量名 表示按引入捕获
- 表示传入参数的列表
- 表示捕获的变量是否在Lambda表达式中可修改
- Lambda表达式抛出的异常
- Lambda表达式的返回值
- Lambda表达式函数体
Lambda表达式的类型是std::function
Lambda表达式使用
了解了Lambda表达式的定义,我们来看看Lambda表达式的使用
不捕获任何变量的
编译运行
注意:由于Lambda表达式是C++11的特性,所以我们在编译的时候需要加上编译参数-std=c++11
Lambda表达式基础用法
下来我们尝试着修改捕获的变量值,代码如下
发现编译报错
这时我们的mutable就派上了用场,修改代码如下
然而问题并没有结束,看下述代码
其实这里即使用了mutable修饰我们的Lambda表达式,在Lambda表达式内修改的也只是name变量的一份copy,如果我们需要在Lambda表达式内修改捕获的变量,我们则需要按照引用捕获,如下
注意:由于是按照引用捕获,所以我们用不用mutable修饰结果一样的
下面我们来看怎么给Lambda表达式传递参数
和普通函数传递参数是一样的,大家可以发挥想象力
Lambda表达式作为参数
前面已经说过Lambda表达式是std::function类型的变量,既然是变量那么必须可以作为参数进行传递,有了上边的描述,直接上代码
至此,关于Lambda表达式的相关内容相信大家已经了然于胸了。