0

I'm running into trouble with the following snippet:

std::promise<int> promise;    
auto operation = [](std::promise<int> promise) { promise.set_value(1); };
auto fn = std::bind(operation, std::move(promise));
fn();

Using clang I get the following error:

candidate template ignored: substitution failure [with _Args = <>]: implicit instantiation of undefined template 'std::__1::__bind_return<(lambda at promise.cpp:7:12), std::__1::tuple >, std::__1::tuple<>, false>' operator()(_Args&& ...__args)

Thanks in advance!

T.C.
  • 133,968
  • 17
  • 288
  • 421
Tim
  • 4,560
  • 2
  • 40
  • 64
  • 2
    You want move capture. `std::bind` can't do that. [Lambda can do it starting with C++14](http://stackoverflow.com/questions/8640393/move-capture-in-lambda), but not in C++11. – Igor Tandetnik Jul 02 '16 at 03:49
  • 2
    @IgorTandetnik `std::bind` can do move captures just fine. The problem is that it passes the captured thing along as an lvalue. – T.C. Jul 02 '16 at 07:36
  • Your title is misleading: there is no `std::function` involved in your current code. – ysdx Jul 02 '16 at 08:04

2 Answers2

1

Bound objects are passed along as lvalues, and promises can't be copied.

Making your lambda take a lvalue reference will make your code compile, but might not be a great idea.

auto operation = [](std::promise<int>& promise) { promise.set_value(1); };
//                                   ^
T.C.
  • 133,968
  • 17
  • 288
  • 421
0

Igor is quite right, but for my purposes this worked quite nicely, and is c++11 compatible:

std::promise<int> promise;    
auto operation = [](std::promise<int>& promise) { promise.set_value(1); };
std::packaged_task<void ()> fn { std::bind(operation, std::move(promise)) };
fn();

By changing operation to take a reference to the std::promise instead of a value, and using std::packaged_task, which is moveable and not copyable, I can achieve the original goal of having a function I can pass around that holds a std::promise.

Tim
  • 4,560
  • 2
  • 40
  • 64
  • Yes sadly, there is no `std::not_packaged_task` which whould avoid the overhead of having a `std::promise` and associated shared state. – ysdx Jul 02 '16 at 08:10