gpt4 book ai didi

c++ - 正 lambda : '+[]{}' - What sorcery is this?

转载 作者:IT老高 更新时间:2023-10-28 11:25:18 27 4
gpt4 key购买 nike

堆栈溢出问题 Redefining lambdas not allowed in C++11, why? ,给出了一个无法编译的小程序:

int main() {
auto test = []{};
test = []{};
}

问题已得到解答,一切似乎都很好。然后来了Johannes Schaub并制作了an interesting observation :

If you put a + before the first lambda, it magically starts to work.

所以我很好奇:为什么以下工作有效?

int main() {
auto test = +[]{}; // Note the unary operator + before the lambda
test = []{};
}

它与 GCC 都可以正常编译4.7+ 和 Clang 3.2+。代码标准符合吗?

最佳答案

是的,代码符合标准。 + 触发转换为 lambda 的普通旧函数指针。

会发生什么:

编译器看到第一个 lambda ([]{}) 并根据 §5.1.2 生成一个闭包对象。由于 lambda 是 非捕获 lambda,因此适用以下情况:

5.1.2 Lambda expressions [expr.prim.lambda]

6 The closure type for a lambda-expression with no lambda-capture has a public non-virtual non-explicit const conversion function to pointer to function having the same parameter and return types as the closure type’s function call operator. The value returned by this conversion function shall be the address of a function that, when invoked, has the same effect as invoking the closure type’s function call operator.

这很重要,因为一元运算符 + 有一组内置的重载,特别是这个:

13.6 Built-in operators [over.built]

8 For every type T there exist candidate operator functions of the form

    T* operator+(T*);

这样,很清楚会发生什么:当运算符 + 应用于闭包对象时,重载的内置候选集包含转换为任意指针和闭包type 只包含一个候选:转换为 lambda 的函数指针。

auto test = +[]{}; 中的test 的类型因此推导出为void(*)()。现在第二行很简单:对于第二个 lambda/closure 对象,对函数指针的赋值会触发与第一行相同的转换。尽管第二个 lambda 具有不同的闭包类型,但生成的函数指针当然是兼容的并且可以分配。

关于c++ - 正 lambda : '+[]{}' - What sorcery is this?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18889028/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com