2010-05-14 10 views
10

Algunos objetos C++ no tienen un constructor de copia, pero tienen el constructor de movimientos. Por ejemplo, boost :: promise. ¿Cómo puedo vincular esos objetos usando sus constructores de movimiento?Cómo usar boost :: bind con params que no se pueden copiar, por ejemplo boost :: promise?

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

utilizando un puntero no es tan raro, que depende de lo que usted está dando a los objetos se unen. Por ejemplo, si está usando señales, puede guardar el objeto Connection y call disconnect en el dtor del objeto. Si no está utilizando señales, podría desarrollar algo similar, o ajustar el puntero en un shared_ptr. – Kyle

+0

boost :: promise, en realidad, es un shared_ptr y un bool. Parece extraño que deba asignarse en el montón y ser rastreado con un shared_ptr más. – user222202

Respuesta

4

no estoy seguro de cómo utilizar un constructor movimiento en su lugar, pero otro enfoque es el uso de impulso :: ref que crea referencias a objetos copiable, y luego se puede pasar a los que se unen al impulso ::.

+0

No boost :: ref solo funciona mientras el objeto se refiera en vivo? –

+0

Sí, así que tendrá que preocuparse por la vida útil de los objetos con los que está trabajando. – swestrup

5

Veo que usted usa std :: move. ¿Por qué no usas std :: bind que debería tener en cuenta la semántica de movimientos?

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

Bl sobre la declaración de una versión del movimiento fullfil_1

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

Boost.Bind qué no se mueven soportes semántica todavía (al menos yo no soy consciente de). Espero que Boost.Move actualmente revisado sea aceptado, y que Boost.Bind, Boost.Lambda y Boost.Phoenix agreguen las interfaces semánticas de movimiento.

Usted puede tratar de componer ref y mover la siguiente manera

boost::function<void()> f_set_one = boost::bind(&fullfil_1, boost::ref(std::move(pi)), 1); 
Cuestiones relacionadas