Questo codice:C++ ottimizzazione del valore di ritorno
#include <vector>
std::vector<float> getstdvec() {
std::vector<float> v(4);
v[0] = 1;
v[1] = 2;
v[2] = 3;
v[3] = 4;
return v;
}
int main() {
std::vector<float> v(4);
for (int i = 0; i != 1000; ++i)
{
v = getstdvec();
}
}
mia comprensione non corretta qui è che la funzione getstdvec non dovrebbe avere per allocare in realtà il vettore che è il ritorno. Quando eseguo questo in valgrind/callgrind, vedo che ci sono 1001 chiamate a malloc; 1 per la dichiarazione iniziale del vettore in main e 1000 per ogni iterazione del ciclo.
Cosa dà? Come posso restituire un vettore (o qualsiasi altro oggetto) da una funzione come questa senza doverla allocare ogni volta?
modifica: sono consapevole di poter passare semplicemente il vettore per riferimento. Avevo l'impressione che fosse possibile (e anche preferibile) scrivere una funzione come questa che restituisca un oggetto senza incorrere in un'assegnazione non necessaria.
Per la modifica: abbiamo bisogno di un esempio reale del problema che stai cercando di risolvere piuttosto che di questo codice di esempio estremamente ridotto per fornire una soluzione non pass-per-referenza. –
@MarkB, è davvero così semplice: voglio una funzione che restituisca un vettore senza dover effettuare una copia/allocazione non necessaria. Avevo l'impressione che qualcosa riguardante RVO o rvalues rendesse possibile questa cosa molto semplice. Un semplice esempio del mondo reale proverebbe a fare y = k * x per i vettori ye x, scalare k. La funzione pass-by-reference tradizionale sembrerebbe 'void mult (const float & k, const vec & x, vec & y)'. Ma chiaramente una chiamata di funzione 'y = mult (k, x)' è preferibile a 'mult (k, x, y)'. – Aurelius
RVO (Return value optimization) è qualcosa che il compilatore fa al tuo codice. Il tuo codice deve prima fare qualcosa che può essere ottimizzato (passa un temporaneo che viene nuovamente assegnato allo stesso oggetto, ad esempio). Potresti aver guardato quel codice e pensato - hmm, potrei ottimizzarlo passando un riferimento a getstdvec. Perché il compilatore non lo fa? Bene, il passaggio di un riferimento NON è implicito nel codice. Puoi solo aspettarti che il compilatore ottimizzi le cose che fa il tuo codice, non cose che potrebbe fare. – iheanyi