Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/164.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ c++;11 lambda真的支持闭包吗?那里';函数变量中的语义冲突_C++_C++11_Variables_Lambda_Scope - Fatal编程技术网

C++ c++;11 lambda真的支持闭包吗?那里';函数变量中的语义冲突

C++ c++;11 lambda真的支持闭包吗?那里';函数变量中的语义冲突,c++,c++11,variables,lambda,scope,C++,C++11,Variables,Lambda,Scope,我个人觉得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

我个人觉得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,%d\n",f1(2),f2(2));
  return 0;
}
#包括
int main()
{
自动f=[](整数输入){
int local=3;
return[=](intx){return input+local+x;};
};
自动f1=f(3);
自动f2=f(4);
printf(“%d,%d\n”,f1(2),f2(2));
返回0;
}
g++-std=c++11,它打印“8,9”

这是我对FP的期望,但是对于C语言范围,它的行为应该是“未定义的”,因为“input”和“local”在“f”声明之后都会消失

因此,问题:

对于输入参数和内部变量,lambda对象是否将它们存储在某个位置以确保它们在lambda定义之后仍然可用?或者我的测试是未定义的行为


谢谢。

Lambdas将捕获的对象存储在其自身中。如果您通过引用捕获,那么您将保留引用,并且需要确保您没有在悬空的引用上操作。如果通过复制进行捕获(如在示例中所做的),则不需要关心原始对象,因为在lambda初始化之后,您将不会使用它们

lambda是未命名的类,但它们可以相当接近普通类;您的示例可以使用
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,%d\n",f1(2),f2(2));
  return 0;
}

以上也符合您的预期:

< P>您试图将“C语言范围”应用到C++中?两种语言,两套规则<代码> f>代码>是一个C++对象,具有一个成员函数,在C中不存在的东西,这就是为什么代码> int局部< /COD>可以具有该成员函数的范围。

< P>编译器基本上为每个lambda创建一个(未命名的)类,并且每个类都将捕获的变量作为成员变量。


这里的另一个作用是通过值进行捕获,这意味着数据被复制。因此变量
input
local
可能超出范围,但这并不重要,因为它们的值被复制到lambda闭包对象中。

您可以通过引用捕获
input
local
变量,在这种情况下,您是对的,这将是未定义的行为。