MHe*_*bes 4 c++ boost-asio c++11 std-future
我正在尝试编写一个相当简单的方法来返回未来。lambda 决定了未来。这是一个最小的例子。实际上,lambda 可能会在不同的线程中调用,等等。
#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)] {
std::error_code error;
p.set_value(error);
};
lambda();
return std::move(fut);
}
int main() { return do_something().get().value(); }
Run Code Online (Sandbox Code Playgroud)
由于某种原因,我收到类型错误。VSCode 智能感知 说:
没有重载函数“
std::promise<_Ty>::set_value [with _Ty=std::error_code]”的实例与参数列表和对象匹配(该对象具有阻止匹配的类型限定符) -- 参数类型为: (std::remove_reference_t<std::error_code &>) -- 对象类型为:const std::remove_reference_t<std::promise<std::error_code> &>
MSVC 编译器说:
错误 C2663: '
std::promise<std::error_code>::set_value': 2 个重载没有对 'this' 指针进行合法转换
我真的不明白 VS Code 错误。它是说它认为error是 aconst promise<error_code>吗?如何正确调用lambda 捕获中的set_value承诺?move
默认情况下,lambda 将所有捕获的值(非引用)存储为const值,您无法修改它们。但lambda支持关键字mutable,你可以这样添加:
[/*...*/](/*...*/) mutable { /*...*/ }
这将允许 lambda 的内部修改其所有值。
如果由于某种原因您无法使用mutable,那么您可以使用其他解决方法:
[/*...*/, p = std::make_shared<ClassName>(std::move(p)), /* ... */](/*...*/) {/*...*/}
换句话说,将移动的值包装到std::shared_ptr中,如果愿意,您也可以使用std::unique_ptr 。
包装成共享指针解决了这个问题,因为共享指针(也是唯一的)允许修改其底层对象值,即使指针本身是const。
不要忘记在 lambda 体内将其p作为指针取消引用,换句话说,如果您使用过p.SomeMethod(),现在您必须使用p->SomeMethod()(with->运算符)。