将c ++ lambda复制到函数指针引用

时间:2018-04-05 07:31:54

标签: c++ lambda scope reference function-pointers

我不确定在以下情况下是否定义了行为:

我的函数指针类型:

typedef void (*DoAfter_cb_type)(void);

应该分配回调的函数:

void DoSomething(DoAfter_cb_type & DoAfter_cb)
{
    //...
    DoAfter_cb =  [](){
        //...
    };
}

呼叫者:

DoAfter_cb_type DoAfter_cb = nullptr;

DoSomething(DoAfter_cb);

// Here is something that has to be done after DoSomething but before DoAfter_cb.

if( DoAfter_cb != nullptr){
    DoAfter_cb();
}

当我了解here时,lambdas可以隐式转换为函数指针。

然而thoose仍然是指针,我担心调用lambda的重要内容存储在堆栈中,如果我只返回函数指针,它将超出范围

我必须使用函数指针,因为我无法在我的环境中访问std :: function。 使用std :: function我希望lambda对象存储在引用变量中,我不会有任何问题。

行为是否相同如果我只是定义一个普通的函数或者我有任何副作用吗?

1 个答案:

答案 0 :(得分:4)

  

行为是否相同如果我只是定义一个普通的函数或者我有任何副作用吗?

是的,它是一样的。无捕获的lambda可以转换为常规函数指针,因为引用C ++标准([expr.prim.lambda.closure]/6,强调我的):

  

非泛型lambda表达式的闭包类型,没有   lambda-capture有一个转换函数来指向函数   C ++语言链接具有相同的参数和返回类型   闭包类型的函数调用操作符。转换是“指针   到noexcept函数“如果函数调用操作符有非抛出   异常规范。 此转化返回的值   function是函数F的地址,当被调用时,它具有   与调用闭包类型的函数调用操作符相同。

因此,当lambda超出范围时,该指针由适当的函数支持,就像您自己在文件范围内编写它一样。功能"直播"在整个程序执行过程中,指针始终有效。