c++11 lambda 真的支持闭包吗?函数变量中存在语义冲突

Does c++11 lambda really support closure? There's a semantic conflict in function variable

本文关键字:变量 存在 语义 冲突 函数 真的 lambda 支持 闭包 c++11      更新时间:2023-10-16

我个人觉得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 捕获,这意味着数据已复制。因此,变量 inputlocal可能会超出范围,但是由于它们的值被复制到lambda闭合对象。

您正在尝试将" C语言范围"应用于C ?两种语言,两组规则。f是具有成员函数的C 对象,这就是int local在C中不存在的东西。