C++ C++;VS2010中带有lambda参数捕获的嵌套lambda bug?

C++ C++;VS2010中带有lambda参数捕获的嵌套lambda bug?,c++,visual-studio-2010,lambda,c++11,C++,Visual Studio 2010,Lambda,C++11,我使用的是Visual Studio 2010,它显然在lambda上有一些错误行为,并且有这个嵌套的lambda,其中内部lambda返回第二个lambda,包装为std::function(cf.): intx=0; 自动lambda=[&](整数n) { 返回std::函数( [&]//注释捕获 { x=n; } ); }; lambda(-10)(;//调用外部和内部lambda 断言(-10==x);//失败! 这将编译,但在断言时失败。具体来说,内部lambda中的n未初始

我使用的是Visual Studio 2010,它显然在lambda上有一些错误行为,并且有这个嵌套的lambda,其中内部lambda返回第二个lambda,包装为std::function(cf.):

intx=0;
自动lambda=[&](整数n)
{ 
返回std::函数(
[&]//注释捕获
{ 
x=n;
} 
); 
};
lambda(-10)(;//调用外部和内部lambda
断言(-10==x);//失败!

这将编译,但在断言时失败。具体来说,内部lambda中的n未初始化(0xCCCC),但x成功修改为其值。如果我将内部lambda的capture子句更改为“[&,n]”,断言将按预期传递。这是VS2010的一个bug还是我不了解lambda捕获是如何工作的?

这不是一个bug,因为
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!
intx=0;
自动lambda=[&](整数n)
{ 
return std::function(//n是“lambda”的本地值,在return语句后被销毁,因此调用std::function时,n的引用捕获无效。
[&]
{ 
x=n;//未定义的行为
} 
); 
};
自动tmp=λ(-10);
//n不再有效
tmp();//调用tmp,该tmp使用n的引用,该引用已被销毁。
断言(-10==x);//失败!

这类似于仅返回简单引用的情况。让你吃惊的是编译器没有发出警告。因此,这不是编译器中的错误,只是缺少警告

std::function<int()> F(int n)
{
    return [&]{ return n; };  //no warning
}
int& F2(int n)
{
    return n; //warning
}
std::函数F(int n)
{
return[&]{return n;};//无警告
}
int&F2(int n)
{
返回n;//警告
}

事实上,我认为编译器应该能够对此发出警告。@mlimber:请记住,VC++2010实现了lambdas pre-,因此它将有许多与嵌套lambdas相关的“不正确”行为。尽管在这种特殊情况下(返回值),您可能是正确的,嵌套Lambda在VS2010中确实错误地失去了作用域:微软声称在其实现中应用了一个修复程序,我们将在未来的版本中看到。
std::function<int()> F(int n)
{
    return [&]{ return n; };  //no warning
}
int& F2(int n)
{
    return n; //warning
}