C++中被lambda移动捕获的promise无法调用set_value如何解决?
问题原因
默认情况下,lambda的函数调用运算符operator()是const修饰的,这意味着所有按值捕获的变量在lambda体内都会被视为const对象。而std::promise<T>::set_value()是一个非const成员函数,不允许在const类型的promise实例上调用,所以触发了类型不匹配的报错。
你看到的报错内容里的object type is const std::promise<std::error_code> &指的是lambda体内访问到的p是const引用类型,和传入的error参数无关,是调用set_value的p本身被判定为const导致的匹配失败。
修复方案
- 方案1(最推荐):给lambda添加
mutable修饰符,取消operator()的const限制,这样就能在lambda体内修改捕获的promise对象,修复后完整代码如下:
#include <future> std::future<std::error_code> do_something() { std::promise<std::error_code> p; auto fut = p.get_future(); auto lambda = [p = std::move(p)]() mutable { std::error_code error; p.set_value(error); }; lambda(); return fut; // 此处不需要显式std::move,编译器会自动做返回值优化 } int main() { return do_something().get().value(); }
加mutable的方案兼容所有使用场景,不管lambda是在当前线程调用还是投递到其他线程执行都可以正常运行。
- 方案2:如果确实需要保持lambda的const属性,也可以用
std::shared_ptr包裹promise后捕获,const lambda中可以通过指针调用promise的非const成员,但写法相对冗余,没有特殊需求不需要用这种方案。
内容的提问来源于stack exchange,提问作者MHebes
相关产品推荐
相关产品推荐

