1.可调用对象(callable object)
对于一个对象或者表达,如果可以使用调用运算符(),则称其为可调用的。
可调用对象种类:
- 函数
- 函数指针
- 重载了()的类
- lambda表达式
2.lambda表达式
lambda包括:返回类型、一个参数列表和一个函数体。形式如下:
[capture list] (parameter list) -> return type {function body}
其中:参数列表和返回类型可以忽略,但:捕获列表和函数体必须包含。
3.lambda的捕获和返回
lambda是一种函数对象,当编写一个lambda表达式后,编译器将该表达式翻译成一个未命名类的未命名对象,在lambda产生的类中含有一个重载的函数调用运算符。
- 捕获引用
lambda通过引用捕获变量时,编译器负责保证lambda执行时,引用对象确实存在。因此,编译器可以直接使用该引用而无需再lambda产生的类中将其存储位数据成员。 - 捕获值
相反,通过值捕获的变量被拷贝到lambda中。因此,这种lambda产生的类必须位每个值捕获的变量建立对应的数据成员,同时创建构造函数,利用捕获的变量的值来初始化数据成员。
- 显示捕获
值捕获:auto f = [v] {return v;};
引用捕获:auto f = [&v] {return v;};
- 隐式捕获
[&]:采用引用捕获方式
[=]:采用值捕获方式
- 混合捕获
当混合使用隐式捕获和显示捕获时,捕获列表中的第一个元素必须是&或者=,后面显示列出,捕获的元素。
4.可变lambda
默认情况下,对于值捕获(值被拷贝)的变量,lambda不会改变其值。如果希望改变捕获的变量的值,则需要在参数列表首加上关键字mutable。引用捕获的变量,自然可以修改。
auto f = [v1] () mutable {return ++v1;};
网友评论