目录
即看即用
语法:
[capture](parameters)->return-type {body}
[]叫做捕获说明符
parameters参数列表
->return-type表示返回类型,如果没有返回类型,则可以省略这部分。
我们可以这样输出"hello,world"
auto func = [] () { cout << "hello,world"; };
func(); // now call the function
变量捕获与lambda闭包实现
string name;
cin >> name;
[&](){cout << name;}();
lambda函数能够捕获lambda函数外的具有自动存储时期的变量。函数体与这些变量的集合合起来叫闭包。
[] 不截取任何变量
[&} 截取外部作用域中所有变量,并作为引用在函数体中使用
[=] 截取外部作用域中所有变量,并拷贝一份在函数体中使用
[=, &foo] 截取外部作用域中所有变量,并拷贝一份在函数体中使用,但是对foo变量使用引用
[bar] 截取bar变量并且拷贝一份在函数体重使用,同时不截取其他变量
[x, &y] x按值传递,y按引用传递
[this] 截取当前类中的this指针。如果已经使用了&或者=就默认添加此选项。
详情
lambda表达是c++中的可调用对象之一,在C++11中被引入到标准库中,使用时不需要包含任何头文件,但是编译时需要指定-std=c++11
或其他支持c++11标准的编译命令(比如-std=c++0x
或-std=c++14
或-std=c++1y
)。lambda表达式源于函数式编程的概念,简单来说它是一个匿名函数。它最大的作用就是不需要额外再写一个函数或者函数对象,避免了代码膨胀功能分散,让开发人员更加集中精力在手边的问题,提高生产效率。
基本概念和用法
c++中,普通的函数是长这样子的:
ret_value function_name(parameter) option { function_body; }
比如:
int get_value(int a) const {return a++;}
lambda表达式定义了一个匿名函数,并且可以捕获所定义的匿名函数外的变量。它的语法形式是:
[ capture ] ( parameter ) option -> return_type { body; };
其中:
- capture 捕获列表
- parameter 参数列表
- option 函数选项
- return_type 函数返回值类型
- body 函数体
比如:
// defination
auto lamb = [](int a) -> int { return a++; };
// usage
std::cout << lamb(1) << std::endl; // output: 2
组成lambda的各部分并不是都必须存在的:
- 当编译器可以推导出返回值类型的时候,可以省略返回值类型的部分
auto lamb = [](int i){return i;}; // OK, return type is int
auto lamb2 = [] () {return {1, 2};}; // Error
- lambda表达式没有参数时,参数列表可以省略
auto lamb = []{return 1;}; // OK
所以一个最简单的lambda表达式可以是下面这样,这段代码是可以通过编译的:
int main()
{
[]{}; // lambda expression
return 0;
}
捕获列表
捕获列表是lambda表达式和普通函数区别最大的地方。[]
内就是lambda表达式的捕获列表。一般来说,lambda表达式都是定义在其他函数内部,捕获列表的作用,就是使lambda表达式内部能够重用所有的外部变量。捕获列表可以有如下的形式:
[]
不捕获任何变量[&]
以引用方式捕获外部作用域的所有变量[=]
以赋值方式捕获外部作用域的所有变量[=, &foo]
以赋值方式捕获外部作用域所有变量,以引用方式捕获foo变量