11

Some C++ objects have no copy constructor, but have move constructor. For example, boost::promise. How can I bind those objects using their move constructors ?

#include <boost/thread.hpp>

void fullfil_1(boost::promise<int>& prom, int x)
{
  prom.set_value(x);
}

boost::function<void()> get_functor() 
{
  // boost::promise is not copyable, but movable
  boost::promise<int> pi;

  // compilation error
  boost::function<void()> f_set_one = boost::bind(&fullfil_1, pi, 1);

  // compilation error as well
  boost::function<void()> f_set_one = boost::bind(&fullfil_1, std::move(pi), 1);

  // PS. I know, it is possible to bind a pointer to the object instead of 
  // the object  itself. But it is weird solution, in this case I will have
  // to take cake about lifetime of the object instead of delegating that to
  // boost::bind (by moving object into boost::function object)
  //
  // weird: pi will be destroyed on leaving the scope
  boost::function<void()> f_set_one = boost::bind(&fullfil_1, boost::ref(pi), 1);
  return f_set_one;
}
user222202
  • 523
  • 4
  • 14
  • Using a pointer isn't that weird, it depends on what you're giving the bind objects to. For example, if you're using signals, you can save the Connection object, and call disconnect in the object's dtor. If you're not using signals, you could develop something similar, or wrap the pointer in a shared_ptr. – Kyle May 14 '10 at 17:13
  • boost::promise, actually, is a shared_ptr and a bool. It seems strange that it should be allocated on heap and be tracked with one more shared_ptr. – user222202 May 14 '10 at 17:36

2 Answers2

5

I'm not sure how to use a move constructor instead, but another approach is to use boost::ref that creates copyable references to objects, and you can then pass those into boost::bind.

swestrup
  • 4,079
  • 3
  • 22
  • 33
5

I see that you uses std::move. Why don't you use std::bind which should be aware of move semantics?

template<class F, class... BoundArgs>
unspecified bind(F&&, BoundArgs&&...);
template<class R, class F, class... BoundArgs>
unspecified bind(F&&, BoundArgs&&...);

Wht about declaring a move version of fullfil_1

void fullfil_1(boost::promise<int>&é prom, int x)
{
  prom.set_value(x);
}

Boost.Bind doesn't supports move semantics yet (at least I'm not aware of). I hope that the currently reviewed Boost.Move will be accepted, and that Boost.Bind, Boost.Lambda and Boost.Phoenix will add the move semantics interfaces.

You can try composing ref and move as follows

boost::function<void()> f_set_one = boost::bind(&fullfil_1, boost::ref(std::move(pi)), 1);
Vicente Botet Escriba
  • 4,305
  • 1
  • 25
  • 39