无法将std::bind与std::promise一起使用

Unable to use std::bind with std::promise

本文关键字:std 一起 promise bind      更新时间:2023-10-16

如果我使用:

int a = 3;
std::function<void()> task1 = std::bind([](int a){}, std::move(a));

可以,但如果我用std::promise<int>:替换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参数有什么问题?

问题是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内部管理的promise。