本文介绍了一个正的拉姆达:'+ [] {}' - 这是什么魔法?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在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.

这篇关于一个正的拉姆达:'+ [] {}' - 这是什么魔法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-01 10:25