函数对象与lambda表达式
Published on
函数对象
函数对象(仿函数/函子)指实现了operator()运算符的类的对象,它的调用方式与函数类似。相对于直接函数调用,函数对象有两个优势:
- 函数对象可包含状态
- 函数对象是一个类型,因此可用作模板参数
class Plus
{
public:
int operator()(int a, int b)
{
return a + b;
}
};
int main()
{
Plus plus;
int n = plus(11, 22);
}
lambda表达式
lambda表达式是C++11引入的一个语法糖,使用它可以方便快捷地创建一个匿名函数对象。
int main()
{
auto plus = [](int a, int b) { return a + b; };
int n = plus(11, 22);
}
组成
一个完整lambda表达式的组成如下:
[ capture-list ] ( params ) mutable(optional) exception(optional) -> ret(optional) { body }
- 捕获列表(capture-list)
- 参数列表(params)
- mutable标识(mutable,可选)
- 异常标识(exception,可选)
- 返回类型(ret,可选)
- 函数体(body)
其中,参数列表、异常标识、返回类型、函数体4部分都与函数基本相同,其它部分说明如下:
捕获列表
捕获列表使lambda表达式可以访问其所在作用域内的变量,捕获的方式有两种:
- 按值捕获:访问变量的副本,修改副本不影响原变量
- 按引用捕获:访问变量的引用,修改引用会修改原变量
这两种捕获方式可以有多种组合:
[] // 不捕获任何变量
[=] // 按值捕获所有用到的变量
[&] // 按引用捕获所有用到的变量
[a] // 按值捕获变量a
[&b] // 按引用捕获变量b
[=, &a] // 按引用捕获变量a,按值捕获其它变量
[&, b] // 按值捕获变量b,按引用捕获其它变量
[a, &b] // 按值捕获变量a,按引用捕获变量b
mutable标识
默认情况下,lambda表达式中值捕获的变量无法修改,如果需要修改,则需指定mutable标识。注意,由于是值捕获,即使可以修改,修改的也是变量的副本,并不影响原变量。