【C++】匿名函数详解

1.概述

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

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

基础示例

#include <iostream>  
  
using namespace std;  
  
int main()  
{  
    auto func = [] () { cout << "Hello world"; };  
    func(); // now call the function  
}
123456789

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

2.lambda表达式

Lambda表达式具体形式如下:

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

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

[capture](parameters){body}
1

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

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

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

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

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

2.2 Lambda函数中的变量截取

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

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

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

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

vector<int> v;  
v.push_back( 1 );  
v.push_back( 2 );  
//...  
for_each( v.begin(), v.end(), [] (int val)  
{  
	cout << val;  
} );  
12345678

而且这么写了之后执行效率反而提高了。因为编译器有可能使用”循环展开“来加速执行过程(计算机系统结构课程中学的)。
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

  • 6
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
c++ 11引入了lambda表达式,它可以看成是一般函数的函数名被略去,返回值使用了一个 "->" 的形式表示。lambda函数带有捕获列表,表示可以在函数体内访问外部的变量。如果捕获列表为空,lambda函数不能使用所在函数中的变量。 lambda函数的使用可以通过函数指针进行转换,但是要求lambda函数没有捕捉到任何变量,并且函数指针所示的函数原型必须和lambda函数有着相同的调用方式。然而,C++11不允许将函数指针转换为lambda函数。 以下是对lambda函数的一些示例代码: 在test01函数中,定义了一个lambda函数Add,它接受两个参数a和b,并返回它们的和。lambda函数被赋值给一个auto类型的变量Add,并通过Add(1, 2)进行调用。 在test07函数中,定义了一个lambda函数Add,它没有返回值。在lambda函数中,试图输出在所在函数中的变量c和d,但由于捕获列表为空,导致编译报错。 在main函数中,使用typedef定义了函数指针类型allChild和oneChild。通过lambda函数totalChild向函数指针p进行转换,因为totalChild没有捕捉到任何变量。但是尝试将totalChild转换给函数指针q会导致编译错误。使用decltype函数可以获取lambda函数的类型,可以将totalChild赋值给allPeople,但是将p赋值给totalPeople会导致编译错误。 总结来说,lambda函数是一种便捷的定义匿名函数的方式,可以通过函数指针进行转换。但在转换过程中要注意捕捉列表和函数原型的要求。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* [C++匿名函数lambda详解](https://blog.csdn.net/Long_xu/article/details/127869979)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *3* [C++11之lambda函数](https://blog.csdn.net/liujun3512159/article/details/122184455)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值