2016-04-01 15 views
5

Non capisco cosa contenga effettivamente un'istanza di std::function.Devo passare std :: function by-value o by (rvalue) -reference?

È più efficiente passarlo per valore o per riferimento?

Quali sono gli effetti delle prestazioni nei seguenti esempi?

by-value:

void printStats(std::function<void(const char *)> printer); 
. . . 
std::string tmp; 
printStats([&tmp](const char * msg){ tmp += msg; }); 

da rvalue riferimento:

void printStats(std::function<void(const char *)>&& printer); 
. . . 
std::string tmp; 
printStats([&tmp](const char * msg){ tmp += msg; }); 
+0

Intendevi al basso per riferimento o per riferimento di rvalue. Il tuo titolo dice una cosa ma il codice un'altra. il riferimento di rvalue e il riferimento di lvalue funzionano in modo diverso. – NathanOliver

+0

Penso che la risposta semplice sia di valore ma solo nel caso in cui non lo sapessi: [quando usare i modelli su 'std :: function'] (http://stackoverflow.com/questions/14677997/stdfunction-vs-template – Maikel

+0

La copia di una 'std :: function' in genere richiede un'assegnazione di memoria dinamica, è quindi piuttosto costosa e dovrebbe quindi essere passata per riferimento. – nwp

risposta

5

Innanzitutto, std::function è necessario per evitare un'assegnazione nel caso in cui il bersaglio è un puntatore funzione di std::reference_wrapper; implementazioni sono encouraged to avoid allocation for "small" targets:

[...] per esempio, dove f s' bersaglio è un oggetto che contiene solo un puntatore o un riferimento a un oggetto e un puntatore funzione membro.

Ciò significa che copiare un std::function cui obiettivo è grande comporterà una ripartizione e una copia del bersaglio (conteggio di riferimento non è consentita, poiché la porta può avere stato mutabile). Tuttavia, nel tuo caso specifico la copia verrà eliminata poiché stai chiamando la tua funzione con un valore provvisorio provvisorio.

Nel caso specifico, dal momento che si sta chiamando la funzione immediatamente non è necessario preoccuparsi di assumerne la proprietà, quindi sarebbe meglio prendere la funzione con riferimento const. Prenderlo per riferimento rvalue causerebbe un mal di testa a un utente che ha un lvalue esistente o un riferimento const a una funzione; avrebbero bisogno di std::move (nel primo caso) o creare una copia temporanea di valore (in quest'ultimo caso).

+1

"Incoraggiato "non è uguale a" richiesto ". Inoltre, il testo citato è in una ** nota ** e le note non sono normative. –

Problemi correlati