返回捕获 lambda 的 lambda 时发出 Clang 警告

Clang warning when returning a lambda-capturing lambda

下面的(简化的)代码试图包装一个 lambda 给了我一些 Clang 版本的警告,但不是所有的,也不是 gcc。

template<typename Lambda>
auto wrapLambda(Lambda lambda)
{
    return [&lambda]() {
        lambda();
    };
}

auto wrappedLambda = wrapLambda([](){ return 0; });
warning: address of stack memory associated with parameter 'lambda' returned [-Wreturn-stack-address]  
    return [&lambda]() {  
             ^~~~~~

这是一个错误,还是我遗漏了什么?我在 godboltclang version 11.1.0 中收到 x86-64 clang (trunk) 的警告作为更大的回购协议的一部分,但我无法隔离该版本的故障。

this related question中的例子没有给出警告。


改进(我认为)版本:

template<typename Callable>
auto wrapCallable(Callable&& callable)
{
    return [callable = std::forward<Callable>(callable)]() {
        callable();
    };
}

auto wrappedCallable = wrapCallable([](){ return 0; });

这会消除 godboltx86-64 clang (trunk) 的警告。我认为它应该可以安全地用于任何仿函数,任何我遗漏的东西?

问题与此代码完全相同:

SomeType& foo(int x)
{
    SomeType bar{x};
    return bar; // undefined behavior returning reference to local object
}

您的 lambda 正在通过引用捕获本地对象,因此当您 return 它时,这将导致未定义的行为,因为捕获的对象不再存在。

当您使用此 lambda 时,很可能程序会崩溃(如果您不走运则不会)。

所以这是你的代码中的错误,clang 正在正确地抱怨。

问题更新后编辑:
更新问题后,新代码会创建 lambda 参数的副本(或移动副本)。结果是 returned lambda 不携带对局部变量的引用,所以现在可以了。