2015-01-29 22 views
7

Quindi stavo cercando di aggiungere numeri interi sul retro del mio vettore e ho pensato erroneamente che push_back() aggiungessero i nuovi dati alla parte anteriore del vettore (ovvero vettore [0]). Ho fatto un test in Xcode e testato push_back() contro emplace_back() e ho ottenuto gli stessi risultati. Pensavo fossero diversi, ma questo mi fa pensare che forse fanno la stessa cosa. Se è così, perché il vettore ha i diversi metodi?Do vector.emplace_back() e vector.push_back() fanno la stessa cosa?

Ecco il mio codice nel caso in cui stavo facendo:

#include <vector> 
#include <iostream> 

using namespace std ; 

int main(int argc, const char * argv[]) 
{ 
    // for push_back 
    vector<int> push; 
    push.push_back(1); 
    push.push_back(2); 
    push.push_back(3); 
    push.push_back(4); 
    push.push_back(5); 
    push.push_back(6); 
    //display push_back 
    for (int i = 0; i < push.size(); i++) { 
     cout << "push[" << i << "]: " << push[i] << endl; 
    } 
    // distance between the two funcitons 
    cout << endl << endl; 

    vector<int> emplace; 
    emplace.emplace_back(1); 
    emplace.emplace_back(2); 
    emplace.emplace_back(3); 
    emplace.emplace_back(4); 
    emplace.emplace_back(5); 
    emplace.emplace_back(6); 

    //display emplace_back 
    for (int i = 0; i < emplace.size(); i++) { 
     cout << "emplace[" << i << "]: " << emplace[i] << endl; 
    } 
     return 0; 
} 

Il ritorno è stato:

push[0]: 1 
push[1]: 2 
push[2]: 3 
push[3]: 4 
push[4]: 5 
push[5]: 6 


emplace[0]: 1 
emplace[1]: 2 
emplace[2]: 3 
emplace[3]: 4 
emplace[4]: 5 
emplace[5]: 6 

So che questa è una domanda super facile, ma voglio solo per assicurarsi che io non sono fare qualcosa di stupidamente sbagliato e fraintendere le abilità della classe vettoriale.

+2

@nawaz Questo duplicato non è molto buono, si tratta di una non conformità dello studio visivo e in realtà non risponde a questa domanda. –

+1

'push_back' usa costruttori copia/sposta, costrutti' emplace_back' in posizione.Credo che 'emplace_back' sia un superset di' push_back', dal momento che è possibile utilizzare i costruttori copia/sposta con la costruzione sul posto. – Suedocode

+0

@Aggieboy: Sì, lo è. E se fosse stato progettato oggi, probabilmente avremmo solo 'emplace_back'. – Deduplicator

risposta

6

La differenza è che emplace_back sarà costruire l'oggetto in alternativa alla loro copia o lo spostamento, cppreference section on std::vector::emplace_back dice:

che utilizza tipicamente posizionamento nuovo per costruire l'elemento posto nella posizione fornita dal contenitore. Gli argomenti args ... vengono inoltrati al costruttore

Questo è importante nel caso di oggetti pesanti. Possiamo vedere che questa è stata la motivazione della original proposal che dice:

La motivazione per l'inserimento posizionamento è che i contenitori, soprattutto nodo basato su contenitori sono molto utili per lo stoccaggio di pesanti oggetti. In alcuni ambienti l'efficienza è molto importante, ma non è in genere possibile inserire elementi in contenitori senza copiare . Un oggetto pesante può memorizzare direttamente i suoi dati, in cui la semantica del movimento di caso non migliorerà le prestazioni di copia. Inoltre, quando l'efficienza è fondamentale, la soluzione non può dipendere dalle ottimizzazioni del compilatore poiché sono opzionali e potrebbero non verificarsi dove sono più necessarie le . L'inserimento dei posizionamenti ci consente di creare un elemento una volta, nel container in cui lo vogliamo, e di non dover mai spostarlo o copiarlo. Lo fa in modo semplice e diretto introducendo le nuove funzioni variadic che accettano argomenti che vengono passati al costruttore dell'elemento utilizzando modelli variadic e inoltro perfetto.

possiamo prendere un esempio dove questo fa una differenza da Effective Modern C++Articolo 42: Si consideri postazione luogo dell'inserimento, che ha il seguente esempio:

std::vector<std::string> vs; // container of std::string 
vs.push_back("xyzzy"); // add string literal 

che si traduce nella creazione di un temporaneo in contrapposizione a:

vs.emplace_back("xyzzy"); 

che non.

+0

'vector :: push_back' in genere utilizza anche il posizionamento nuovo. –

+4

Dovrebbe forse essere menzionato (poiché l'OP ha chiesto questo), che 'push_back' e' emplace_back' sono esattamente gli stessi nel caso in cui abbiamo già un oggetto esistente che vogliamo copiare/spostare nel vettore; sono diversi solo quando contemporaneamente costruiamo e spingiamo, come nel tuo esempio. –