使用c++参数lambda函数
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);
和
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; });
在这里,我们使用一个通过引用捕获的变量来存储(并更新)vector中所有数字的和。
花点时间来思考这个例子,做一些你自己的实验,这就是关于lambda的所有知识。:)
[&]
捕获列表确保lambda定义周围作用域中的变量可以在lambda函数体中被引用使用。
所以是:在第一个代码片段中,b
在lambda中是可用的(只是不要忘记结束函数赋值的半列)。你甚至可以改变它的值(影响get_allowed()
中的b
会改变function1()
的参数b
的值,因为它是通过引用捕获的)!
在第二个代码片段中,按值传递b
作为参数。这是不同的。b是通过值传递的参数的名称,它与封闭作用域的b无关。
补充说明
注意:如果你的lambda在定义它的作用域中存活(例如,如果你从function1()
返回lambda或存储get_allowed
的值),你可能会遇到引用捕获的问题;稍后在另一个上下文中调用lambda可能会引用不再存在的变量(悬空引用)。
如果您更喜欢松散耦合,您可以考虑使用[=]
捕获列表:它具有类似的效果,但捕获的变量是按值传递的(即没有意外修改或悬空引用)。这使得lambda更加独立于创建它的上下文。
在第一个示例中,get_allowed
是一个参数函数,其中b
被隐式捕获(因为您使用[&]
捕获)。
在第二个函数中,get_allowed
是一个有两个参数的函数,其中b
显式传递给get_allowed
,而不是从周围的函数中获取。
lambda在本例中是不必要的,所以两者的区别有点学术性。
在这种情况下,我可以在lambda函数内使用b吗??
是的,你可以在lambda中使用b
。
[&]通过引用捕获lambda主体中使用的所有自动变量
b
被引用
- 可组合的lambda/std::函数与std::可选
- C++Boost Asio Pool线程,带有lambda函数和传递引用变量
- 如何建立使用模板函数的lambda函数的尾部返回类型
- 如何将lambda作为模板类的成员函数参数
- 我可以将调用类的"this"传递给 lambda 函数吗?
- 模板函数指针和lambda
- 两组使用lambda函数的大括号
- 尝试将lambda函数放在队列中时出现一般分配器错误(可能是与unique_ptr有关的错误)
- 我可以在这里替换什么,因为我不能在 C# 中使用隐式变量的 lambda 函数?
- 在构造函数中使用 lambda 的 C++ 类
- 如何调用存储在指向"std::函数"的指针中的 lambda?
- 为什么我不能在 constexpr lambda 函数中使用 std::tuple
- 从具有按值捕获的 lambda 移动构造 std::函数时,移动构造函数调用两次
- C++:Lambda 函数指针转换的用例是什么?
- 将有状态的 lambda 传递到 C 样式函数中,而无需上下文参数
- std::映射服装比较函数和函数/lambda错误
- 在可移动类型的构造函数 lambda 中捕获此内容的安全使用
- 排序测试模板化函数 lambda:非法使用此类型作为表达式
- 将匿名函数(lambda)保存为函数类型变量
- 如何编写将自身作为回调传递的匿名函数/lambda