Как использовать boost :: bind с не копируемыми параметрами, например, boost :: prom? - PullRequest
10 голосов
/ 14 мая 2010

Некоторые объекты C ++ не имеют конструктора копирования, но имеют конструктор перемещения. Например, повысить :: обещание. Как я могу связать эти объекты, используя их конструкторы перемещения?

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

Ответы [ 2 ]

5 голосов
/ 26 мая 2010

Я вижу, что вы используете std :: move. Почему бы вам не использовать std :: bind, который должен знать семантику перемещения?

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

Как объявить ходовую версию fullfil_1

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

Boost.Bind пока не поддерживает семантику перемещения (по крайней мере, я не в курсе). Я надеюсь, что рассмотренный в настоящий момент Boost.Move будет принят и что Boost.Bind, Boost.Lambda и Boost.Phoenix добавят интерфейсы семантики перемещения.

Вы можете попробовать составить ссылку и двигаться следующим образом

boost::function<void()> f_set_one = boost::bind(&fullfil_1, boost::ref(std::move(pi)), 1);
4 голосов
/ 14 мая 2010

Я не уверен, как использовать вместо этого конструктор перемещения, но другой подход заключается в использовании boost :: ref, который создает копируемые ссылки на объекты, а затем вы можете передать их в boost :: bind.

...