如果我使用:
int a = 3;
std::function<void()> task1 = std::bind([](int a){}, std::move(a));
没关系,但如果我用int
替换std::promise<int>
:
std::promise<int> p;
std::function<void()> task2 = std::bind([](std::promise<int> p){}, std::move(p));
G ++会抛出错误:
error: conversion from ‘std::_Bind_helper<false, main()::__lambda7, std::promise<int> >::type {aka std::_Bind<main()::__lambda7(std::promise<int>)>}’ to non-scalar type ‘std::function<void()>’ requested
std::function<void()> task2 = std::bind([](std::promise<int> p){}, std::move(p));
为什么呢?绑定std::promise
参数的问题是什么?
答案 0 :(得分:5)
问题是std::function
要求内部类型可以复制。该属性适用于第一个示例(int
),但不适用于第二个示例(std::promise
仅移动)。请注意,如果您不使用std::function
并直接调用lambda,则代码可以正常工作:
std::bind([](std::promise<int>& p) { p.set_value(42); }, std::move(p))();
要使用std::function
,您需要将promise包装到某种包装器中。标准std::reference_wrapper
应该足够了:
std::promise<int> p;
std::function<void()> foo = std::bind([](std::promise<int>& p) {}, std::ref(p));
foo();
但是,您需要担心原始p
变量的生命周期。另一种选择是在std::shared_ptr
内传递承诺。