2012-05-07 15 views
7

Questa è presumibilmente una semplice domanda C++, ma sto riapprendendo il C++ e non conosco alcune delle nozioni di base. Ho una classe che include una struttura con un vettore di oggetti in esso, in modo da qualcosa di simile:aggiungi al vettore senza copiare i dati della struct

struct my_struct{ 
    Irrelevant_Object object, 
    vector<tuple> tuple_list; 
} 

La struct e la tupla (un'altra struct) sono predefiniti dal architettura e dato a me nel mio metodo; quindi non posso cambiarli. Voglio generare e inserire una tupla nella tuple_list vuota originale.

La soluzione semplice è un metodo che assegna un nuovo oggetto tupla, inserisce i dati della tupla, quindi chiama tuple_list.push_back() e passa la tupla assegnata. Ma ciò richiederebbe l'allocazione di una nuova tupla solo per fare in modo che il metodo push_back copi tutto il contenuto della (tupla) struttura tundle in uno spazio di memoria già definito del vettore. Quindi sto pagando le spese di un allocazione/cancellazione e anche la minore spesa di copiare i contenuti della tupla nel vettore per farlo in questo modo. Sembra piuttosto inefficace, e dato che questo metodo sarebbe nel percorso critico della funzione preferirei qualcosa di più veloce (ammetto che dubito che questo metodo sarebbe il collo-bottiglia, e so che l'ottimizzazione iniziale == male. Comunque, io sono ponendo questa domanda in più per imparare qualcosa sulla sintassi del C++ e poi su un bisogno disperato di farlo nel mio codice).

Quindi la mia domanda è, c'è un modo più veloce per riempire il contenuto della mia lista tupla senza allocare e copiare una tupla? Se questo fosse un array, potrei rendere l'array grande quanto voglio, quindi passare un riferimento a tuple_list [0] alla funzione che crea la tupla. In questo modo la funzione potrebbe riempire il contenuto vuoto della tupla già allocata all'interno dell'array senza allocarne uno nuovo o copiare da una tupla a un'altra. Ho provato a farlo con il vettore per curiosità e ho finito con un errore di seg quando il mio itteratore indicava 0x0, quindi presumo che la sintassi non funzioni per i vettori. Quindi c'è un modo veloce per fare questo incarico?

Poiché questa è una domanda tanto per imparare la lingua quanto per l'uso reale, sentiti libero di gettare qualsiasi altra roba tangenzialmente rilevante che pensi sia interessante, sto cercando di imparare.

Grazie.

+0

Controllare i costruttori sovraccaricati di 'std :: vector' e fornire un elenco di costruttori e inizializzatori per la propria struttura, forse?Altrimenti puoi sempre "riservare" il tuo vettore allo spazio di cui hai bisogno in modo che la chiamata "push_back" utilizzi lo spazio disponibile e non abbia un costo di allocazione elevato. Serve un esempio più tangibile e usa il caso per fornire una risposta reale. – AJG85

risposta

15

In C++ 11, è possibile utilizzare std::vector::emplace_back, che crea il nuovo oggetto sul posto, pertanto non viene eseguita alcuna copia quando si utilizza questo metodo.

Utilizzando questo metodo, si potrebbe fare questo:

my_struct some_struct; 
some_struct.tuple_list.emplace_back(1, 5, "bleh"); 

Supponendo che l'oggetto contiene tuple questo costruttore:

tuple::tuple(int, int, const std::string&) 

Modifica: È anche possibile utilizzare move semantics per memorizzare un pre- tupla assegnata:

my_struct some_struct; 
tuple a_tuple; 
/* modify a_tuple, initialize it, whatever... */ 
some_struct.push_back(std::move(a_tuple)); // move it into your vector 

Oppure utilizzare un riferimento al tuple dopo che è stato immagazzinato nel vettore:

my_struct some_struct; 
some_struct.tuple_list.emplace_back(1, 5, "bleh"); 
// store a reference to the last element(the one we've just inserted) 
tuple &some_tuple = some_struct.tuple_list.back(); 
some_tuple.foo(); 

Su tutte le soluzioni di cui sopra si sta creando un solo tuple allo stesso tempo evitare la copia.

+0

questo è quasi esattamente quello che voglio (supponendo che abbiamo installato C++ 11, controllerò due volte). Tuttavia, poiché la tupla è grande, preferirei passare un riferimento alla tupla del vettore (o spazio allocato per la tupla) a un metodo e creare il contenuto su un elemento variabile uno alla volta. Esiste un metodo simile che restituisca un riferimento alla tupla pre-allocata che posso utilizzare? – dsollen

+0

Ecco qua, edita la risposta: D. – mfontanini

+0

ottima risposta! grazie. – dsollen

Problemi correlati