2010-05-14 5 views
10

Alcuni oggetti C++ non hanno un costruttore di copia, ma hanno un costruttore di mosse. Ad esempio, boost :: promise. Come posso legare quegli oggetti usando i loro costruttori di movimento?Come utilizzare boost :: bind con parametri non copiabili, ad esempio 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

utilizzando un puntatore non è che strano, dipende da quello che si sta dando gli oggetti l'associazione. Ad esempio, se stai usando segnali, puoi salvare l'oggetto Connection e chiamare disconnect nel dtor dell'oggetto. Se non stai usando i segnali, potresti sviluppare qualcosa di simile, o avvolgere il puntatore in un parametro shared_ptr. – Kyle

+0

boost :: promise, in realtà, è un shared_ptr e un bool. Sembra strano che dovrebbe essere allocato su heap e tracciabile con un altro shared_ptr. – user222202

risposta

4

non sono sicuro di come utilizzare un costruttore mossa, invece, ma un altro approccio è quello di usare boost :: ref che crea i riferimenti copiabili agli oggetti, e si può quindi passare quelle in boost :: bind.

+0

Non boost: ref funziona solo fino a quando l'oggetto si riferisce a live? –

+0

Sì, quindi dovresti preoccuparti della durata di vita degli oggetti con cui lavori. – swestrup

5

Vedo che usi std :: move. Perché non usi std :: bind che dovrebbe essere a conoscenza della semantica del movimento?

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

Wht sulla dichiarazione di una versione mossa di fullfil_1

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

Boost.Bind non lo fa è favorevole ancora semantica (almeno io non sono a conoscenza di). Spero che il Boost.Move recensito al momento sia accettato e che Boost.Bind, Boost.Lambda e Boost.Phoenix aggiungano le interfacce di semantica del movimento.

si può provare a comporre ref e muoversi come segue

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