问题描述
在Stack Overflow问题 ,a小程序没有编译:
int main(){
auto test = [] {};
test = [] {};
}
问题得到解答,似乎都很好。然后发表了:
所以我很好奇:为什么下面的工作?
int main(){
auto test = + [] {}; //注意一元运算符+在lambda之前
test = [] {};
}
它与 4.7+和 3.2+。代码标准是否符合?
是的,代码是标准符合的。 + 触发一个转换为lambda的简单旧函数指针。
p>
编译器看到第一个lambda( [] {} ),并根据§5.1.2生成一个闭包对象。由于lambda是不捕获 lambda,以下内容适用:
这是很重要的,因为一元运算符 + 有一组内置的重载,特别是这一个:
c $ c> + 应用于闭包对象,重载的内置候选对象集包含一个转换为任意指针,闭包类型只包含一个候选对象:转换为函数
test 在中的类型auto test = + [ {};因此推导出 void(*)()。现在第二行很容易:对于第二个lambda / closure对象,对函数指针的赋值触发与第一行相同的转换。即使第二个lambda有不同的闭包类型,生成的函数指针当然是兼容的,可以分配。
In Stack Overflow question Redefining lambdas not allowed in C++11, why?, a small program was given that does not compile:
int main() { auto test = []{}; test = []{}; }
The question was answered and all seemed fine. Then came Johannes Schaub and made an interesting observation:
So I'm curious: Why does the following work?
int main() { auto test = +[]{}; // Note the unary operator + before the lambda test = []{}; }
It compiles fine with both GCC 4.7+ and Clang 3.2+. Is the code standard conforming?
Yes, the code is standard conforming. The + triggers a conversion to a plain old function pointer for the lambda.
What happens is this:
The compiler sees the first lambda ([]{}) and generates a closure object according to §5.1.2. As the lambda is a non-capturing lambda, the following applies:
This is important as the unary operator + has a set of built-in overloads, specifically this one:
And with this, it's quite clear what happens: When operator + is applied to the closure object, the set of overloaded built-in candidates contains a conversion-to-any-pointer and the closure type contains exactly one candidate: The conversion to the function pointer of the lambda.
The type of test in auto test = +[]{}; is therefore deduced to void(*)(). Now the second line is easy: For the second lambda/closure object, an assignment to the function pointer triggers the same conversion as in the first line. Even though the second lambda has a different closure type, the resulting function pointer is, of course, compatible and can be assigned.
这篇关于一个正的拉姆达:'+ [] {}' - 这是什么魔法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!