Différence d’insertion et push_back du vecteur C ++

Je veux savoir quelles sont les différences entre les fonctions push_back et insert vector .

Y a-t-il une ou plusieurs différences structurelles?

Y a-t-il une très grande différence de performance?

La plus grande différence est leur fonctionnalité. push_back place toujours un nouvel élément à la fin du vector et insert vous permet de sélectionner la position d’un nouvel élément. Cela affecte la performance. vector éléments vector sont déplacés dans la mémoire uniquement lorsqu’il est nécessaire d’augmenter sa longueur car trop peu de mémoire lui a été allouée. D’autre part, insert forces pour déplacer tous les éléments après la position sélectionnée d’un nouvel élément. Vous devez simplement faire une place pour cela. C’est pourquoi insert souvent moins efficace que push_back .

Les fonctions ont des objectives différents. vector::insert vous permet d’insérer un object à une position spécifiée dans le vector , alors que vector::push_back va simplement coller l’object à la fin. Voir l’exemple suivant:

 using namespace std; vector v = {1, 3, 4}; v.insert(next(begin(v)), 2); v.push_back(5); // v now contains {1, 2, 3, 4, 5} 

Vous pouvez utiliser insert pour effectuer le même travail que push_back avec v.insert(v.end(), value) .

Outre le fait que push_back(x) fait la même chose que insert(x, end()) (peut-être avec des performances légèrement meilleures), il y a plusieurs choses importantes à savoir sur ces fonctions:

  1. push_back n’existe que sur les conteneurs BackInsertionSequence – par exemple, il n’existe pas sur set . Il ne pourrait pas parce que push_back() vous accorde qu’il appenda toujours à la fin.
  2. Certains conteneurs peuvent également satisfaire à FrontInsertionSequence et ils ont push_front . Ceci est satisfait par deque , mais pas par le vector .
  3. L’ insert(x, ITERATOR) provient de InsertionSequence , qui est commun pour set et vector . De cette façon, vous pouvez utiliser le set ou le vector comme cible pour plusieurs insertions. Cependant, set a en outre insert(x) , ce qui fait pratiquement la même chose (ce premier insert dans set signifie seulement accélérer la recherche de l’endroit approprié en partant d’un autre iterator – une fonctionnalité non utilisée dans ce cas).

Notez à propos du dernier cas que si vous voulez append des éléments dans la boucle, alors container.push_back(x) et container.insert(x, container.end()) feront la même chose. Cependant, cela ne sera pas vrai si vous obtenez ce container.end() premier et que vous l’utilisez ensuite dans toute la boucle.

Par exemple, vous pourriez risquer le code suivant:

 copy(a.begin(), a.end(), inserter(v, v.end()); 

Cela copiera effectivement tout a dans a vecteur v , dans l’ordre inverse , et seulement si vous avez la chance de ne pas réallouer le vecteur pour l’extension (vous pouvez empêcher cela en appelant en premier Reserve). Si vous n’êtes pas aussi chanceux, vous obtiendrez ce que l’on appelle un comportement indéfini ™. Théoriquement, cela n’est pas autorisé car les iterators de vecteurs sont considérés comme invalidés chaque fois qu’un nouvel élément est ajouté.

Si vous le faites de cette façon:

 copy(a.begin(), a.end(), back_inserter(v); 

il va copier a à la fin de v dans l’ordre d’origine, et cela ne comporte pas de risque d’invalidation de l’iterator.