在C ++ 11中,是" lambda函数"与" lambda表达相同"和"关闭"?

时间:2016-06-09 05:47:34

标签: c++ c++11 lambda closures evaluation

在cppreference网站上,当谈到direct_initialization时,它说它在闭包参数捕获中工作,如... {...} 我认为这应该是" lambda function",但为什么它也被称为" closure"?

我检查了C ++ 11标准,项目"关闭"首先出现在第5.1.2节(lambda表达式)中,其中说:

The evaluation of a lambda-expression results in a prvalue temporary (12.2). This temporary is called the 
closure object. A lambda-expression shall not appear in an unevaluated operand (Clause 5). [ Note: A 
closure object behaves like a function object (20.8). — end note ] 

那么如何理解"评估lamdba表达"?这个"评估"在编译或运行时发生了什么? C ++ 11中是否有差异,其中包括" lambda表达式"," lambda函数"和" closure"?

我不是在谈论像Closure这样的其他编程语言,只关注C ++ 11。 谢谢。

2 个答案:

答案 0 :(得分:3)

什么是闭包(引自wikipedia):

  

在编程语言中,闭包(也是词法闭包或函数   闭包)是一种实现词法范围名称的技术   用一流函数绑定语言。 操作上,a   闭包是一个记录函数 [a] 和一个   环境:关联每个自由变量的映射   函数(在本地使用但在。中定义的变量)   封闭范围)与名称的值或存储位置   在创建闭包时绑定了 [b] 。关闭,   与普通函数不同,允许函数访问捕获的函数   变量通过闭包引用它们,即使是在   函数在其范围之外调用。

     

[a] 该函数可以存储为函数的引用,   例如函数指针。

     

[b] 这些名称最常引用值,可变   变量或函数,但也可以是其他实体,如   常量,类型,类或标签。

什么是lambda表达式(引自wikipedia):

  

在计算机编程中,匿名函数(函数文字,   lambda abstraction)是一个未绑定到的函数定义   标识符

     

从C ++ 11开始,C ++支持匿名函数,称为 lambda   表达式,其格式为:

[capture](parameters) -> return_type { function_body }
     

示例lambda函数定义如下:

[](int x, int y) -> int { return x + y; }
     

从C ++ 11开始,C ++也支持闭包。闭包在两者之间定义   lambda表达式声明中的方括号[和]。该   机制允许通过值或通过值捕获这些变量   参考。下表演示了这一点:

[]        //no variables defined. Attempting to use any external variables in the lambda is an error.
[x, &y]   //x is captured by value, y is captured by reference
[&]       //any external variable is implicitly captured by reference if used
[=]       //any external variable is implicitly captured by value if used
[&, x]    //x is explicitly captured by value. Other variables will be captured by reference
[=, &z]   //z is explicitly captured by reference. Other variables will be captured by value

<强>恢复

术语 Lambda表达式 Lambda函数可互换使用,用于表示匿名函数对象的定义/声明:

[capture](parameters) -> return_type { function_body }

使用术语闭包,我们引用通过评估 lambda 表达式创建的运行时函数对象。

现在要在编译时评估lambdas,这需要lambda作为常量表达式。不幸的是,lambdas不是constexpr,因此无法在编译时进行评估。但是,提交给委员会N4487的提案表明,通过取消一些限制,我们可以constexpr lambdas。也就是说,将来我们可能会有constexpr lambdas,可以在编译时进行评估。

答案 1 :(得分:0)

Lambda表达式与其他表达式类似,默认情况下在运行时进行计算。评估表达式1 + 2给出int,其值为3.评估lambda表达式[] { return 0; }给出一个闭包对象,它也是一个函数对象,operator()()是一个函数返回0。

简而言之,闭包对象是一个运行时对象,就像C ++中的任何其他对象一样,lambda表达式是一个结果是闭包对象的表达式。