user2364011
user2364011

Reputation: 71

Unable to bind function to std::function<void()> when passing a std::move() object as a function argument

Trying to compile this following snippet of code:

#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);

}

Getting the following error:

In function 'int main()': 15:90: error: conversion from 'std::_Bind_helper&&, int), std::promise, int>::type {aka std::_Bind, int))(std::promise&&, int)>}' to non-scalar type 'std::function' requested

I know it has something to do with the function argument std::promise&& and the need for std::move, but I'm stuck.

Upvotes: 0

Views: 367

Answers (2)

Ruifeng Xie
Ruifeng Xie

Reputation: 906

Maybe you should use a move-capturing lambda instead of a 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); };
}

The only drawback is that you need c++14 enabled to compile this code.

Upvotes: 0

rafix07
rafix07

Reputation: 20936

bind returns object of unspecified type which holds moved promise (noncopyable object) as data member. function is wrapper for Callable object, one of requirement of instance of function is to make the copy of stored Callable, in your case object returned from bind cannot be passed into function, because the copy cannot be made due to promise as data member.

You should use auto to deduce type of bind's result.

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();
}

Upvotes: 2

Related Questions