将std :: move()对象作为函数参数传递时,无法将函数绑定到std :: function <void()>

时间:2019-01-24 02:39:39

标签: c++11 std-function stdbind stdmove

尝试编译以下代码段:

#include <iostream>
#include <future>
#include <functional> 

void print_num(std::promise<bool>&& result, int i )
{
    std::cout << i << " " << '\n' ;
    result.set_value(true);
}

int main()
{
   std::promise<bool> Promise0;
   std::future<bool> Result0 = Promise0.get_future();      
   std::function<void()> f_display_31337 = std::bind(print_num, std::move(Promise0), 31337);

}

出现以下错误:

在函数'int main()'中:15:90:错误:从'std :: _ Bind_helper &&,int),std :: promise,int> :: type {aka std :: _ Bind,int))( std :: promise &&,int)>}'转换为非标量类型'std :: function'的请求

我知道它与函数参数std :: promise &&和对std :: move的需求有关,但我被困住了。

3 个答案:

答案 0 :(得分:1)

也许您应该使用move捕获lambda而不是std::bind

int main()
{
   std::promise<bool> Promise0;
   std::future<bool> Result0 = Promise0.get_future();      
   std::function<void()> f_display_31337 =
      [Promise0 = std::move(Promise0)] mutable
      { print_num(std::move(Promise0), 31337); };
}

唯一的缺点是您需要启用c++14来编译此代码。

答案 1 :(得分:1)

bind返回未指定类型的对象,该对象将移动的promise(不可复制对象)保留为数据成员。 function是Callable对象的包装器,function实例的要求之一是使存储的Callable的副本成为可能,因为从bind返回的对象无法传递给函数,因为由于promise为数据成员,因此无法进行复制。

您应该使用auto来推断绑定结果的类型。

void print_num(std::promise<bool>& result, int i )
{
    std::cout << i << " " << '\n' ;
    result.set_value(true);
}

int main()
{
   std::promise<bool> Promise0;
   std::future<bool> Result0 = Promise0.get_future();      

   auto obj = std::bind(print_num, std::move(Promise0), 31337);
   obj();
}

答案 2 :(得分:0)

如果可以将std::promise&&更改为std::promise&,将std::move更改为std::ref

相关问题