You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

传给std::async的变量离开作用域后代码是否合法?

std::async传递std::future的作用域合法性问题

请问如下代码片段是否合法?顾虑点为:当factorial函数被异步调用时,块作用域内定义的fut_num可能已经离开作用域被销毁。

第一份测试代码

#include <future>
#include <vector>
#include <iostream>

// int factorial(std::future<int> fut) // 可正常运行,因std::future存在移动构造函数
int factorial(std::future<int>&& fut)
{
    int res = 1;
    int num = fut.get();

    for(int i = num; i > 1; i--)
    {
        res *= i;
    }

    return res;
}

int main()
{
    std::promise<int> prs;
    std::vector<std::future<int>> vec;

    {
        std::future<int> fut_num{prs.get_future()};
        vec.push_back(std::async(std::launch::async, factorial, std::move(fut_num)));
    }  // fut_num在此处离开作用域
    
    prs.set_value(5);

    for(auto& fut: vec)
    {
        std::cout << fut.get() << std::endl;
    }
}

第二份相似测试代码

#include <future>
#include <vector>
#include <iostream>

// int factorial(std::future<int> fut) // 可正常运行,因std::future存在移动构造函数
int factorial(std::future<int>& fut)
{
    int res = 1;
    int num = fut.get();

    for(int i = num; i > 1; i--)
    {
        res *= i;
    }

    return res;
}

int main()
{
    std::promise<int> prs;
    std::vector<std::future<int>> vec;

    {
        std::future<int> fut_num{prs.get_future()};
        vec.push_back(std::async(std::launch::async, factorial, std::ref(fut_num)));
    }  // fut_num在此处离开作用域
    
    prs.set_value(5);

    for(auto& fut: vec)
    {
        std::cout << fut.get() << std::endl;
    }
}

合法性判断结论

  • 第一份代码完全合法:std::async会将传入的所有参数按值存储在自身的内部共享状态中,此处传入std::move(fut_num)会触发std::future的移动构造,生成一个独立的std::future实例,生命周期归async的内部状态管理,和块作用域内的原fut_num对象完全解耦。即使原fut_num在块结束时被销毁,async持有的移动后实例依然有效,函数的右值引用参数可以正常绑定到该内部实例,后续调用get()不存在悬空引用问题。
  • 第二份代码属于未定义行为,不合法:此处通过std::ref(fut_num)传入的是原块作用域内fut_num对象的左值引用,std::async内部仅存储该引用,不会拷贝或移动future对象本身。当块作用域结束后,原fut_num被销毁,后续异步线程调用factorial访问该引用时,引用已经悬空,属于典型的对象生命周期错误。

补充说明:如果将factorial的参数改为按值接收std::future<int> fut,传入参数时会触发移动构造生成独立的future实例,不会出现上述生命周期问题。

内容的提问来源于stack exchange,提问作者John

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.02 02:28:03