c++11 lambda 真的支持闭包吗?函数变量中存在语义冲突
Does c++11 lambda really support closure? There's a semantic conflict in function variable
我个人觉得C 11 lambda与C/C 功能有一定的冲突,在此功能局部变量的寿命随函数而结束,但是在FP中,Lambda是一个对象,因此变量只要lambda就具有生命周期。
我有一个小测试
#include<stdio.h>
int main()
{
auto f=[](int input){
int local=3;
return [=](int x){return input+local+x;};
};
auto f1=f(3);
auto f2=f(4);
printf("%d,%dn",f1(2),f2(2));
return 0;
}
g -std = C 11,它打印" 8,9"
这是我对FP的期望,但是对于C语言范围,其行为应该是"未定义"的,因为"输入"answers"本地"在" F"声明后死亡。
所以问题:
对于输入参数和内部变量,lambda对象是否将它们存储在某个地方,以确保它们在lambda定义之后仍然可用吗?还是我的测试是未定义的行为?
谢谢。
lambdas存储本身捕获的对象。如果您通过参考捕获,则保留参考,并需要确保您不会在悬空中进行操作。如果您通过复制捕获(如示例中所做的那样),则不需要关心原始对象,因为无论如何您都不会在lambda初始化之外使用它们。
lambdas是未命名的类,但是正常类可以相当紧密地近似;您的示例可以用unnamed
类(而不是实际未命名的lambda)重写:
int main()
{
auto f=[](int input){
int local=3;
struct unnamed {
unnamed(int input, int local) : input(input), local(local) {}
auto operator()(int x) const { return input + local + x; }
int input, local;
};
return unnamed(input, local);
};
auto f1=f(3);
auto f2=f(4);
printf("%d,%dn",f1(2),f2(2));
return 0;
}
上面的表现也如您所期望的:demo
编译器基本上将为每个lambda创建一个(未命名的)类,每个这样的类都将捕获的变量作为成员变量。
也在游戏中,您可以通过 value 捕获,这意味着数据已复制。因此,变量 input
和 local
可能会超出范围,但是由于它们的值被复制到lambda闭合对象。
您正在尝试将" C语言范围"应用于C ?两种语言,两组规则。f
是具有成员函数的C 对象,这就是int local
在C中不存在的东西。
相关文章:
- 为什么我的变量存在于其范围之外
- "new"创建的实例的所有成员变量是否都存在于堆上而不是堆栈上?
- 如何从文件中存在的路径中检索环境变量
- 如何通过结构中的变量找出结构向量中是否存在结构
- VS 中的 C++ 17 会导致 C++14 中不存在的变量(重新)评估错误
- OpenACC vs C++:致命错误:设备上部分存在变量
- 变量在临时存储中存在多长时间
- 对条件表达式结果的赋值(其中第二个和第三个操作数是相同类型和值类别的变量)是否仍然存在?
- 根据成员变量的类型是否存在,有条件地定义该变量
- SFINAE:检测成员变量的存在在 g++ 上不起作用
- 返回成员变量(如果存在)
- 为什么堆栈中的函数局部变量之间存在内存空间
- 原子线程围栏:为什么在这个非原子变量上存在数据竞争?这有关系吗
- 当变量仍然存在时调用C++析构函数
- c++11 lambda 真的支持闭包吗?函数变量中存在语义冲突
- 是否存在32位变量无法正确对齐的情况
- 防止变量脱离范围,因此它们仍然存在另一个线程
- 当只有一个线程写入 c++ 中的布尔变量时,是否存在争用条件
- 保存在 16 位的双变量样本中
- C++.继承和初始化成员变量存在编译错误