无法使用std::bind与std::promise

3

如果我使用:

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 参数有问题?
1个回答

6
问题在于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变量的生命周期。另一种选项是将promise传递给一个在std::shared_ptr内管理的对象。


你说得对。看起来std::function需要一个可复制的类型。我会使用std::shared_ptr代替。非常感谢! - Xiaojie Chen

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接