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

mil*_*712 4 c++ lambda scope function-pointers reference

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

我的函数指针类型:

typedef void (*DoAfter_cb_type)(void);
Run Code Online (Sandbox Code Playgroud)

应该分配回调的函数:

void DoSomething(DoAfter_cb_type & DoAfter_cb)
{
    //...
    DoAfter_cb =  [](){
        //...
    };
}
Run Code Online (Sandbox Code Playgroud)

呼叫者:

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();
}
Run Code Online (Sandbox Code Playgroud)

正如我在这里了解到的,lambda 可以隐式转换为函数指针。

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

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

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

Sto*_*ica 5

\n

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

\n
\n\n

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

\n\n
\n

不带 lambda 捕获的非泛型 lambda 表达式的闭包类型有一个转换函数,指向具有 C++ 语言链接的函数指针,该链接具有与闭包类型的函数调用相同的参数和返回类型操作员。如果函数调用运算符具有非抛出异常规范,则转换为 \xe2\x80\x9cpointer\n 到 noexcept function\xe2\x80\x9d。此转换函数返回的值是函数 F 的地址,调用该函数时,与调用闭包类型的函数调用运算符具有相同的效果。

\n
\n\n

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

\n