使用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,后续的获取请求直接返回缓存值。具体修改如下:
- 在
skein类中新增一个缓存成员变量,用于存储已获取的结果 - 改造
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
相关产品推荐
相关产品推荐

