如果我们看一下C标准草案第5.1.2节,第2段说:
对lambda表达式的求值会产生一个prvalue临时(12.2)。这个临时称为闭包对象。lambda表达式不得出现在未求值的操作数中(第5条)。[注意:闭包对象的行为类似于函数对象(20.8)。-结束注释]
和节5.19
常量表达式第2段说:
条件表达式是核心常量表达式,除非它涉及以下其中一个作为潜在求值子表达式(3.2),但不考虑未求值的逻辑AND(5.14)、逻辑OR(5.15)和条件(5.16)运算的子表达式[…]
并有以下要点:
-lambda表达式(5.1.2);
那么,为什么在未赋值的操作数中不允许lambdas表达式,但在常量表达式的未赋值部分中允许lambdas表达式呢?
我可以看出,对于未赋值的操作数,在几种情况下(decltype或typeid),类型信息不是很有用,因为每个lambda都有一个唯一的类型。虽然我们不清楚为什么要在常量表达式的未赋值上下文中允许它们,也许是为了允许SFINAE?
C标准核心语言缺陷报告和接受的问题#1607中介绍了未评估操作数排除的核心原因。模板参数中的Lambdas旨在澄清此限制,并在5.1.2
节中说明限制的意图是:
[...]避免在函数模板签名中处理它们的需要[...]
由于问题记录了当前的措辞,实际上有一个漏洞,因为常量表达式允许它们在未评估的上下文中使用。但它没有明确说明这种限制的理由。避免名称混乱的愿望很突出,你可以推断,避免延长SFINAE也是需要的,因为提议的决议寻求收紧限制,即使有几个可行的替代方案会允许SFINAE。5.1.2
第2段的修改版本如下:
lambda表达式不得出现在未计算的操作数(第5条[exr])、模板参数、别名声明、typedef声明或函数或函数模板在其函数体和默认参数之外的声明中[注意:目的是防止lambda出现在签名中-结束注释]。[注意:闭包html" target="_blank">对象的行为类似于函数对象(20.10[function.objects])。-结束注释]
该提案已被接受,并在N3936
中(有关链接,请参阅此答案)
以更明确地讨论避免将lambda作为未赋值操作数的原理。讨论题为“lambda表达式在comp上未经评估的上下文中不被允许的理由”。lang.cpp。主持人丹尼尔·克鲁格勒列举了三个原因:
[...]它们被排除在外的原因正是因为sfinae案例的这种极端扩展(你正在为编译器打开一个潘多拉盒子)[…]
在许多情况下,这是无用的,因为每个lambda都有一个唯一的类型,假设的例子如下:
template<typename T, typename U>
void g(T, U, decltype([](T x, T y) { return x + y; }) func);
g(1, 2, [](int x, int y) { return x + y; });
声明和调用中lambda的类型不同(根据定义),因此这无法工作。
名称损坏也成为一个问题,因为一旦在函数签名中允许lambda,lambda的主体也必须损坏。这意味着制定规则来破坏每一条可能的语句,这至少会给某些实现带来负担。
问题内容: 最近我遇到了一个问题:赋值运算符链理解。 在回答这个问题,我开始怀疑我自己的加法赋值运算符的行为的理解或任何其他(,,等)。 我的问题是,下面的表达式中的变量何时更新到位,以便其更改的值在求值过程中反映在表达式的其他位置,其背后的逻辑是什么?请看以下两个表达式: 表达式1 表达式2 在第一个表达式中,当计算最里面的表达式时,似乎不更新的值,因此结果是而不是。 但是,在第二个表达式中,的
最近我遇到了这样一个问题:作业操作员链理解。 在回答这个问题时,我开始怀疑自己对加法赋值运算符或任何其他(
(译注:目前支持lambda的gcc编译器版本为4.5,其它详细的编译器对于C++11新特性的支持请参考http://wiki.apache.org/stdcxx/C%2B%2B0xCompilerSupport) Lambda表达式是一种描述函数对象的机制,它的主要应用是描述某些具有简单行为的函数(译注:Lambda表达式也可以称为匿名函数,具有复杂行为的函数可以采用命名函数对象,当然,何谓复杂
PEP 572引入了为Python 3.8实现的赋值表达式(俗称Walrus操作符)。这似乎是一个非常重要的新特性,因为它将允许在理解和lambda函数中进行这种形式的赋值。 赋值表达式的语法、语义学和语法规范到底是什么? 为什么在PEP 379中关于“添加赋值表达式”的类似想法之前遭到拒绝的情况下,引入了这个新的(似乎相当激进的概念)?
Lambda表达式在Java 8中引入,并被吹捧为Java 8的最大特性.Lambda表达式有助于函数式编程,并简化了很多开发。 语法 (Syntax) lambda表达式的特征在于以下语法。 parameter -> expression body 以下是lambda表达式的重要特征。 Optional type declaration - 无需声明参数类型。 编译器可以从参数的值推断出相同的