如何将本地引用的变量传递给lambda函数,但是当它的闭包已经完成时将调用该函数?

 你问什么只为她停留_538 发布于 2023-02-06 15:14

下面的代码应该打印两个相同的整数,但事实并非如此.JavaScript中的类似程序会打印两个相同的数字.

在C++中似乎是合理的,因为当stdfun执行时,regfun已经完成,那时local_var 就不存在了.

所以我的问题是我们如何正确地访问捕获的局部变量超出其上下文的生命周期,就像JavaScript默认情况下那样?

#include 
#include 
#include 
#include 
#include 
#include 
using namespace std;

int start_stdfun_in_a_new_thread(std::function stdfun)
{   
    int id = rand();
    std::function call = [=]()
    {
        Sleep(1000);//let regfun finish 
        stdfun();
    };
    std::async(std::launch::async,call);
    return id;
}

void regfun()
{
    int local_var = -1;
    std::function stdfun = [=,&local_var]() mutable -> void
    {
        cout<

很难描述我的问题到底是什么,但我只需要像cavascript一样在c ++中使用的东西.如果你对javascript非常熟悉,也许你可以理解我的意思.

1 个回答
  • local_var当地环境的束缚,即它在regfun退出时就已经死了,几乎立刻就会发生.但是你的lambda通过引用捕获它,这意味着在稍后执行时它是一个悬空引用stdfun,因为那时local_var已经死了.

    所以这是未定义的行为.你需要什么(JavaScript做什么)是延长捕获变量的生命周期.但是,正如http://en.cppreference.com/w/cpp/language/lambda中所解释的那样,C++ 11 lambda不是这种情况:

    悬挂参考文献

    如果通过引用(隐式或显式)捕获实体,并且在实体的生存期结束后调用闭包对象的函数调用操作符,则会发生未定义的行为.C++闭包不会延长捕获的引用的生命周期.

    我看到两个解决方案:

      一种解决方案是对要捕获的对象进行堆分配,使用a指向它std::shared_ptr,并按捕获此指针(将其复制到lambda实例中).然后,最后一个共享指针实例将为您删除堆分配的对象.

      如果可能的话,你也可以在其他一些上下文中定义它,在这种情况下,在每种情况下都超过了它的使用寿命.(在您的简单代码中main,但在大多数情况下,您希望等待线程;启动和等待线程的上下文很可能是正确的上下文.)然后通过regfun引用传递给它,并且也通过引用捕获它.因此,即使regfun退出,它仍然是一个有效的参考(如果它在一个生存的背景下).

    2023-02-06 15:15 回答
撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有