这个问题是我最近一个问题的延续:
What is this compiler error when using a lambda as a template parameter?
十一月2014年11月11日:微软已经回复说,这个bug的修复程序应该出现在Visual C ++的下一个主要版本中。
此代码无法使用VS2012(Update 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
r
不是 f
的推断返回类型是一个函数指针,即int (__cdecl *)(void)
?答案 0 :(得分:2)
尽管GCC 4.7.2编译了这段代码,但它形成了错误。初始化f
的lambda表达式太复杂,无法推断返回类型。确实,5.1.2 / 4说
如果lambda表达式不包含trailing-return-type,那就好像trailing-return-type表示以下类型:
- 如果复合语句的格式为
{ attribute-specifier-seq[opt] return expression ; }
lvalue-to-rvalue转换(4.1),数组到指针转换(4.2)和函数到指针转换(4.3)之后返回表达式的类型;
- 否则,无效。
因此,在此示例中,返回类型为void
,但lambda返回其他内容。代码不应该编译。
我同意Visual Studio提供的消息具有误导性。
更新:关于这个问题
所以说&#34;在C ++ 11中,你不能定义一个返回有状态lambda的lambda&#34 ;?
没有。根据下面的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;
}