这个问题是我最近的一个问题的延续:
What is this compiler error when using a lambda as a template parameter?
十一月2014 年 1 月 11 日:Microsoft 已回应称,此错误的修复应该出现在 Visual C++ 的下一个主要版本中。
此代码无法使用 VS2012(更新 2)编译:
int main(int argc, char* argv[])
{
auto f = []()
{
int n = 0;
auto r = [=]{ return n; };
return r;
};
return 0;
}
这是我得到的编译器错误:
1> main.cpp
1>C:\test\main.cpp(7): error C2440: 'return' : cannot convert from 'main::<lambda_c5d1d707b91a1ddedc06eb080503550c>::()::<lambda_ac357c309731f4971c3269160ed9c24b>' to 'int (__cdecl *)(void)'
1> No user-defined-conversion operator available that can perform this conversion, or the operator cannot be called
- C++11规范的代码有问题吗?
- 根据 VS2012 定义的部分 C++11 支持,代码是否存在问题?
- 或者这是 VS2012 C++ 编译器错误?
- 有人可以指出 C++11 规范中讨论 lambda 必须如何隐式转换为函数指针的地方吗?
- 我记得这只适用于无状态 lambda - 那些带有空捕获子句的 lambda - 内部 lambda
r
不是 - 那么为什么lambda
f
的推断返回类型会出现为函数指针,即int (__cdecl *)(void)
?
- 我记得这只适用于无状态 lambda - 那些带有空捕获子句的 lambda - 内部 lambda
最佳答案
尽管 GCC 4.7.2 编译了这段代码,但它的格式不正确。初始化 f
的 lambda 表达式对于推导返回类型来说太复杂了。事实上,5.1.2/4 说
If a lambda-expression does not include a trailing-return-type, it is as if the trailing-return-type denotes the following type:
— if the compound-statement is of the form
{ attribute-specifier-seq[opt] return expression ; }
the type of the returned expression after lvalue-to-rvalue conversion (4.1), array-to-pointer conversion (4.2), and function-to-pointer conversion (4.3);
— otherwise, void.
因此,在此示例中,返回类型为 void
但 lambda 返回的是其他内容。代码不应编译。
我同意 Visual Studio 给出的信息具有误导性。
更新:关于这个问题
So would it be correct to say "In C++11, you cannot define a lambda that returns a stateful lambda"?
没有。根据下面的 C++11 引用,lambda 返回的类型是 void
,除非 lambda 的主体仅包含一行带有 return expression;
。因此,如果您设法在返回表达式中创建有状态的 lambda,那么这很好。例如,下面的代码可以在 GCC 4.7.2、Clang 3.2 和 Intel 编译器 13.1.0 中编译:(由于上述错误,它无法在 VS2012 中编译。)
#include <iostream>
int main() {
int n = 5;
auto f = [=] {
return [=]{ return n; }; // creates a stateful lambda and returns it in a single line
};
std::cout << f()() << std::endl;
return 0;
}
关于c++ - Lambda 返回 lambda 错误地推断返回类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16726014/