C++ 不能为在 lambda 中捕获的承诺移动调用 set_value?
C++ cannot call set_value for promise move-captured in a lambda?
我正在尝试编写一个相当简单的方法 returns 一个未来。 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(); }
出于某种原因,我遇到了类型错误。 VSCode 智能感知说:
no instance of overloaded function "std::promise<_Ty>::set_value [with _Ty=std::error_code]
" matches the argument list and object (the object has type qualifiers that prevent a match) -- argument types are: (std::remove_reference_t<std::error_code &>
) -- object type is: const std::remove_reference_t<std::promise<std::error_code> &>
并且 MSVC 编译器说:
error C2663: 'std::promise<std::error_code>::set_value
': 2 overloads have no legal conversion for 'this
' pointer
VS Code 报错我实在是看不懂。是说它认为error
是一个const promise<error_code>
吗?如何在 lambda 捕获中 move
d 的承诺上正确调用 set_value
?
默认情况下,lambda 将所有捕获的值(非引用)存储为 const
值,您无法修改它们。但是lambda支持关键字mutable
,你可以这样添加:
[/*...*/](/*...*/) mutable { /*...*/ }
这将允许 lambda 的内部主体修改其所有值。
如果由于某种原因您无法使用 mutable
,那么您可以使用其他解决方法:
[/*...*/, p = std::make_shared<ClassName>(std::move(p)), /* ... */](/*...*/) {/*...*/}
换句话说,如果您愿意,可以将移动的值包装到 std::shared_ptr, you can also use std::unique_ptr 中。
包装到共享指针解决了这个问题,因为共享指针(也是唯一的)允许修改它的底层对象值,即使指针本身是 const
.
不要忘记在 lambda 的主体内将 p
取消引用为指针,换句话说,如果您使用 p.SomeMethod()
,现在您必须使用 p->SomeMethod()
(与->
运算符)。
我正在尝试编写一个相当简单的方法 returns 一个未来。 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(); }
出于某种原因,我遇到了类型错误。 VSCode 智能感知说:
no instance of overloaded function "
std::promise<_Ty>::set_value [with _Ty=std::error_code]
" matches the argument list and object (the object has type qualifiers that prevent a match) -- argument types are: (std::remove_reference_t<std::error_code &>
) -- object type is:const std::remove_reference_t<std::promise<std::error_code> &>
并且 MSVC 编译器说:
error C2663: '
std::promise<std::error_code>::set_value
': 2 overloads have no legal conversion for 'this
' pointer
VS Code 报错我实在是看不懂。是说它认为error
是一个const promise<error_code>
吗?如何在 lambda 捕获中 move
d 的承诺上正确调用 set_value
?
默认情况下,lambda 将所有捕获的值(非引用)存储为 const
值,您无法修改它们。但是lambda支持关键字mutable
,你可以这样添加:
[/*...*/](/*...*/) mutable { /*...*/ }
这将允许 lambda 的内部主体修改其所有值。
如果由于某种原因您无法使用 mutable
,那么您可以使用其他解决方法:
[/*...*/, p = std::make_shared<ClassName>(std::move(p)), /* ... */](/*...*/) {/*...*/}
换句话说,如果您愿意,可以将移动的值包装到 std::shared_ptr, you can also use std::unique_ptr 中。
包装到共享指针解决了这个问题,因为共享指针(也是唯一的)允许修改它的底层对象值,即使指针本身是 const
.
不要忘记在 lambda 的主体内将 p
取消引用为指针,换句话说,如果您使用 p.SomeMethod()
,现在您必须使用 p->SomeMethod()
(与->
运算符)。