当前位置:   article > 正文

【C++】匿名函数详解_c++ 匿名函数

c++ 匿名函数

1.概述

匿名函数(英文名:lambda)就是没有名字的函数。最简单的匿名函数是{},它没有参数也没有返回值。在匿名函数中,[]里面用来捕获函数外部的变量,而()里面就是匿名函数的参数,{}里面就是函数的执行代码。

匿名函数,也成lambda函数或lambda表达式

基础示例

#include <iostream>  
  
using namespace std;  
  
int main()  
{  
    auto func = [] () { cout << "Hello world"; };  
    func(); // now call the function  
}
123456789
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

其中func就是一个lambda函数。我们使用auto来自动获取func的类型,这个非常重要。定义好lambda函数之后,就可以当这场函数来使用了。

2.lambda表达式

Lambda表达式具体形式如下:

[capture](parameters)->return-type{body}
1
  • 1
  • 2

如果没有参数,空的圆括号()可以省略.返回值也可以省略,如果函数体只由一条return语句组成或返回类型为void的话.形如:

[capture](parameters){body}
1
  • 1
  • 2

下面举了几个Lambda函数的例子:

[](int x, int y) { return x + y; } // 隐式返回类型 
[](int& x) { ++x; } // 没有return语句 -> lambda 函数的返回类型是'void' 
[]() { ++global_x; } // 没有参数,仅访问某个全局变量 
[]{ ++global_x; } // 与上一个相同,省略了()
1234
  • 1
  • 2
  • 3
  • 4
  • 5

可以像下面这样显示指定返回类型:

[](int x, int y) -> int { int z = x + y; return z; }
1
  • 1
  • 2

在这个例子中创建了一个临时变量z来存储中间值. 和普通函数一样,这个中间值不会保存到下次调用. 什么也不返回的Lambda函数可以省略返回类型, 而不需要使用 -> void 形式.

2.2 Lambda函数中的变量截取

Lambda函数可以引用在它之外声明的变量. 这些变量的集合叫做一个闭包. 闭包被定义在Lambda表达式声明中的方括号[]内. 这个机制允许这些变量被按值或按引用捕获.下面这些例子就是:

[]			//不截取任何变量,试图在Lambda内使用任何外部变量都是错误的(全局变量除外).
[&]			//截取外部作用域中所有变量,并作为引用在函数体中使用
[=] 		//截取外部作用域中所有变量,并拷贝一份在函数体中使用
[=, &foo]   //截取外部作用域中所有变量,并拷贝一份在函数体中使用,但是对foo变量使用引用
[bar]   	//截取bar变量并且拷贝一份在函数体重使用,同时不截取其他变量
[this]		//截取当前类中的this指针。如果已经使用了&或者=就默认添加此选项。
-----------------------------
[x, &y]  	//x 按值捕获, y 按引用捕获.
[&, x]		//x显式地按值捕获. 其它变量按引用捕获
[=, &z]		//z按引用捕获. 其它变量按值捕获
12345678910
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

3.Lambda函数和STL

lambda函数的引入为STL的使用提供了极大的方便。比如下面这个例子,当你想便利一个vector的时候,原来你得这么写:

vector<int> v;  
v.push_back( 1 );  
v.push_back( 2 );  
//...  
for ( auto itr = v.begin(), end = v.end(); itr != end; itr++ )  
{  
    cout << *itr;  
}  
12345678
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

现在有了lambda函数你就可以这么写

vector<int> v;  
v.push_back( 1 );  
v.push_back( 2 );  
//...  
for_each( v.begin(), v.end(), [] (int val)  
{  
	cout << val;  
} );  
12345678
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

而且这么写了之后执行效率反而提高了。因为编译器有可能使用”循环展开“来加速执行过程(计算机系统结构课程中学的)。
http://www.nwcpp.org/images/stories/lambda.pdf 这个PPT详细介绍了如何使用lambda表达式和STL

参考资料:
https://blog.csdn.net/xiaoguyin_/article/details/79798362
https://www.cnblogs.com/pzhfei/archive/2013/01/14/lambda_expression.html
https://www.cnblogs.com/lidabo/p/3908663.html

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小惠珠哦/article/detail/958957
推荐阅读
相关标签
  

闽ICP备14008679号