Как использовать boost:: bind с не скопируемыми параметрами, например boost:: prom?
Некоторые объекты С++ не имеют конструктора копирования, но имеют конструктор перемещения.
Например, boost:: prom.
Как связать эти объекты с помощью их конструкторов перемещения?
#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;
}
Ответы
Ответ 1
Я вижу, что вы используете std:: move. Почему бы вам не использовать std:: bind, который должен знать о семантике перемещения?
template<class F, class... BoundArgs>
unspecified bind(F&&, BoundArgs&&...);
template<class R, class F, class... BoundArgs>
unspecified bind(F&&, BoundArgs&&...);
Wht о объявлении версии перемещения 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 добавят интерфейсы семантики перемещения.
Вы можете попробовать составить ref и двигаться следующим образом
boost::function<void()> f_set_one = boost::bind(&fullfil_1, boost::ref(std::move(pi)), 1);
Ответ 2
Я не уверен, как использовать конструктор move вместо этого, но другой подход - использовать boost:: ref, который создает скопированные ссылки на объекты, и вы можете передать их в boost:: bind.