VS2010 中的 C++ 嵌套 lambda 错误,带有 lambda 参数捕获?
Posted
技术标签:
【中文标题】VS2010 中的 C++ 嵌套 lambda 错误,带有 lambda 参数捕获?【英文标题】:C++ nested lambda bug in VS2010 with lambda parameter capture? 【发布时间】:2011-09-07 03:46:31 【问题描述】:我正在使用 Visual Studio 2010,它显然在 lambdas 上有一些错误的行为,并且有这个嵌套的 lambda,其中内部 lambda 返回一个包装为 std::function 的第二个 lambda(参见"Higher-order Lambda Functions" on MSDN):
int x = 0;
auto lambda = [&]( int n )
return std::function<void()>(
[&] // Note capture
x = n;
);
;
lambda( -10 )(); // Call outer and inner lambdas
assert( -10 == x ); // Fails!
这编译但在断言处失败。具体来说,内部 lambda 中的 n 未初始化(0xCCCCCCCC),但 x 已成功修改为其值。如果我将内部 lambda 的捕获子句更改为“[&,n]”,则断言按预期通过。这是 VS2010 的错误还是我不明白 lambda 捕获是如何工作的?
【问题讨论】:
【参考方案1】:这不是错误,因为 n
在 lambdas return 语句后超出范围,因此引用捕获在您使用时无效。
int x = 0;
auto lambda = [&]( int n )
return std::function<void()>( // n is local to "lambda" and is destroyed after return statement, thus when you call the std::function, the reference capture of n is invalid.
[&]
x = n; // Undefined behaviour
);
;
auto tmp = lambda(-10);
// n is no longer valid
tmp(); // calling tmp which uses reference of n which is alrdy destroyed.
assert( -10 == x ); // Fails!
【讨论】:
我实际上认为编译器应该能够警告这一点。 @mlimber :请记住,VC++ 2010 在N2927 之前实现了 lambda,因此它会有许多与嵌套 lambda 相关的“不正确”行为。 虽然在这种特殊情况下(有返回)你可能是正确的,嵌套的 Lambda 确实在 VS2010 中错误地失去了范围:connect.microsoft.com/VisualStudio/feedback/details/537366/… Microsoft 声称已经在他们的实现中应用了一个修复程序,我们'会在未来的版本中看到。【参考方案2】:这类似于只返回一个简单引用的情况。引起你注意的是编译器没有发出警告。所以这不是编译器的错误,只是缺少警告。
std::function<int()> F(int n)
return [&] return n; ; //no warning
int& F2(int n)
return n; //warning
【讨论】:
以上是关于VS2010 中的 C++ 嵌套 lambda 错误,带有 lambda 参数捕获?的主要内容,如果未能解决你的问题,请参考以下文章
使用C++在vs平台上编译了一个函数出现了如下情况,哪儿错了?怎么改?
为啥我在vs 2012 写c++的时候 定义一个常量,值是中文会报错,error: C2001: 常量中有换行符?