[英]Use parameter lambda function C++
我有这段代码:
void function1(char c, bool b){
auto get_allowed = [&](int x){
if(b){
.... some code...
}
...some code...
}
get_allowed(0);
...other_code...
}
在这种情况下,我可以在lambda函数中使用b吗?
我的意思是,将该参数添加到lambda函数的签名中是一样的事情,例如:
void function1(char c, bool b){
auto get_allowed = [&](int x,bool b){
if(b){
.... some code...
}
...some code...
}
get_allowed(0, false);
...other_code...
}
为了澄清,区别在这里:
auto get_allowed = [&](int x){
get_allowed(0);
VS
auto get_allowed = [&](int x,bool b){
get_allowed(0, false);
其中b是函数function1的参数。
在您的示例中,两个版本的lambda的效果大致相同。 但是, 捕获的参数与“正常”参数之间存在显着差异。
这是lambda的创建方式:
[ capture-list ] ( params ) { body }
capture-list
可让您访问lambda范围内存在的变量。 有一些不同的捕获模式:
[&]
通过引用捕获周围范围内的所有局部变量(即示例中的b
和c
) [&b]
仅通过引用捕获b
,您可以根据需要放置任意数量的命名变量(逗号分隔) [=]
通过值捕获周围范围内的所有局部变量(换句话说:您的lambda拥有这些变量的副本) [b]
仅捕获副本b
[b, &c]
您可以混合使用副本和参考捕获 您应该问自己: 这些捕获是为了什么?
好吧,它定义了一个闭包 ,一个上下文 , 每次使用lambda时都是相同的 。 在许多情况下,添加到函数顶部的这种状态非常有用。
一个示例:您正在将lambda映射到集合的每个元素上:
std::vector<int> numbers = {1, 2, 3, 4, 5};
int sum = 0;
std::for_each(std::begin(numbers), std::end(numbers),
[&sum](int n){ sum += n; });
在这里,我们使用通过引用捕获的变量来存储(和更新)向量中所有数字的总和。
花一些时间思考一下这个示例,自己做一些实验,这就是关于lambda的所有知识。 :)
在第一个示例中, get_allowed
是一个参数的函数,其中b
是隐式捕获的(因为您是使用[&]
捕获的)。
在第二个中, get_allowed
是两个参数的函数,其中b
显式传递给get_allowed
而不是从周围的函数中获取。
在此示例中,lambda是不必要的,因此差异有些学术性。
[&]
捕获列表确保lambda定义范围内的变量可以通过lambda函数主体中的引用来使用。
所以是的:在第一个代码段中, b
在lambda中可用(只是不要忘记半列来结束函数赋值)。 您甚至可以更改其值(在get_allowed()
影响b
会更改function1()
的参数b
的值,因为它被引用捕获了)!
在第二个片段中,按值传递b
作为参数。 这是不同的。 b是按值传递的参数的名称,它与封闭范围的b没有关系。
补充说明
注意:如果您的lambda保留了定义它的范围(例如,如果您要从function1()
返回lambda或存储get_allowed
的值), get_allowed
引用捕获可能会出现问题; 稍后在另一个上下文中调用lambda可以引用不再存在的变量(悬挂引用)。
如果您更喜欢宽松的耦合,则可以考虑使用[=]
捕获列表:它具有类似的效果,但是捕获的变量按值传递(即,无意修改也没有悬挂引用)。 这使lambda在创建它的上下文中更加独立。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.