在lambda中捕获std :: function对象

ave*_*bin 5 c++ compiler-construction lambda clang c++11

当我在最后一行调用s_capture_void_int()并且我不明白为什么时,下面的代码在BAD_ACCESS失败.我想当我将lambda表达式赋给全局变量时,它应该将自己与捕获的值一起复制.所以在我的理解中,不应出现悬挂引用.但看起来我错过了一些东西.

std::function<void()> s_capture_void_int;
void capture_void_int (const std::function<void(int)>& param)
{
    s_capture_void_int = [param]() {
        param(1);
    };
}
void capture_local_lambda()
{
    auto local_lambda = [](int) {
    };
    s_capture_void_int = [local_lambda]() {
        local_lambda(1);
    };
}
BOOST_AUTO_TEST_CASE( test_lambda_captures )
{
    //Case 1: this works
    auto func2 = [](int){};
    {
        std::function<void(int)> func2_fn(func2);
        s_capture_void_int = [func2_fn]() { func2_fn(1); };
    }
    s_capture_void_int();

    //case 2: even this works.
    capture_local_lambda();
    s_capture_void_int();

    //case 3: but this fails.
    auto func3 = [](int){};
    {
        std::function<void(int)> func3_fn(func3);
        capture_void_int(func3_fn);
    }
    s_capture_void_int(); //<- it crashes here
}
Run Code Online (Sandbox Code Playgroud)

我不明白这里有两件事:

  • 如果由于func3_fn超出范围而发生崩溃,那么为什么案例1和2有效?
  • 如果我将此代码更改为std :: function(注意没有参数),那么它可以正常工作.它可能是编译器错误吗?

Rei*_*ica 1

我想说这是一个编译器错误。它在 GCC 中运行良好。也许paramincapture_void_int被错误地通过引用捕获(因为它是一个引用),而实际上它应该通过值捕获。