- mongodb - 在 MongoDB mapreduce 中,如何展平值对象?
- javascript - 对象传播与 Object.assign
- html - 输入类型 ="submit"Vs 按钮标签它们可以互换吗?
- sql - 使用 MongoDB 而不是 MS SQL Server 的优缺点
堆栈溢出问题 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 = []{};
}
最佳答案
是的,代码符合标准。 +
触发转换为 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/
我是一名优秀的程序员,十分优秀!