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

使用Boost.Fiber的future时为何出现访问未初始化future的异常?

使用Boost.Fiber的future时为何出现访问未初始化future的异常?

我来帮你拆解问题根源,再给出可行的解决办法:

问题核心:Future是「一次性消费」的对象

不管是Boost.Fiber的future还是C++标准库的std::future,都遵循一次性消费的规则:当你调用get()方法时,会把future内部的计算结果转移出来,之后这个future就会进入未初始化/无效状态,不能再调用wait()、get()这类依赖内部状态的方法——这就是你触发future_uninitialized异常的直接原因。

看你main函数里的关键代码:

auto sk = new echo_int(5);
auto ivv = sk->m_future.get(); // 第一次调用get(),已经耗尽了m_future的内部状态
std::cout << "Value: " << *ivv << std::endl;
auto vv = sk->get_ptr(); // 这里调用get_ptr()会触发wait(),但m_future已经失效

第一次直接访问m_future.get()已经把future的状态消费完了,后续调用get_ptr()时,它会尝试对已经失效的m_future执行wait()操作,自然就抛出了异常。

解决方案:缓存结果,避免重复操作Future

你需要修改skein类,把future的结果缓存起来,确保只消费一次future,后续的获取请求直接返回缓存值。具体修改如下:

  1. 在skein类中新增一个缓存成员变量,用于存储已获取的结果
  2. 改造get_ptr()方法,优先返回缓存值,仅在缓存为空时才去操作future

修改后的skein.hpp核心部分:

template <typename T>
class skein {
public:
    using value_type = T;
    using ptr_type = std::shared_ptr<T>;

    virtual ~skein() = default;
    skein() : m_future(boost::fibers::async(std::bind(&skein<value_type>::func_p, this))) {};

    skein(const skein &) = delete;
    skein(skein &&) = delete;

    void wait() { 
        if (!m_cached_result) { // 仅缓存为空时才等待
            m_future.wait(); 
        }
    };

    ptr_type get_ptr() {
        if (!m_cached_result) {
            wait();
            m_cached_result = m_future.get(); // 仅消费一次future
        }
        return m_cached_result;
    };

    value_type *get() { return get_ptr().get(); }

protected:
    virtual value_type func() = 0;
    ptr_type func_p() { return std::make_shared<T>(func()); }

private:
    boost::fibers::future<ptr_type> m_future;
    ptr_type m_cached_result; // 新增:缓存计算结果
};

同时,建议你修改main函数,不要直接访问类的内部成员m_future,始终通过公共接口操作,从根源避免状态错误:

auto main() -> int {
    std::unique_ptr<echo_int> sk = std::make_unique<echo_int>(5); // 用智能指针避免内存泄漏
    auto ivv = sk->get_ptr(); // 通过公共接口获取结果
    std::cout << "Value: " << *ivv << std::endl;
    
    auto vv = sk->get_ptr(); // 第二次调用直接返回缓存值,不会触发future操作
    if (*vv == 5) {
        std::cout << "OK: " << sk->get() << std::endl;
        return 0;
    } else {
        std::cerr << "Unexpected Value: " << *vv << std::endl;
        return 1;
    }
}

额外小提示

  • 尽量避免直接访问类的私有/保护成员,依赖公共接口能大幅降低状态类错误的概率
  • 用std::unique_ptr或std::shared_ptr代替裸指针,避免手动管理内存时出现泄漏

内容来源于stack exchange

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.08 07:53:00