web-dev-qa-db-fra.com

Copier std :: vector: préférez l’affectation ou std :: copy?

J'ai deux vecteurs:

std::vector<int> v1, v2;

// Filling v1
...

Et maintenant, je dois copier v1 Dans v2. Y a-t-il une raison de préférer

v2 = v1;

à

std::copy (v1.begin(), v1.end(), v2.begin());

(ou vice versa)?

50
Violet Giraffe

Généralement, je préférerais fortement v2 = v1:

  1. Il est plus court et rend l'intention plus claire
  2. std::copy Ne fonctionnera pas si v2 N'a pas la même longueur que v1 (Il ne le redimensionnera pas, il conservera donc certains des anciens éléments. (v2.size() > v1.size() et écraser certaines données aléatoires utilisées ailleurs dans le pire des cas du programme
  3. Si v1 Est sur le point d'expirer (et que vous utilisez C++ 11), vous pouvez facilement le modifier en move le contenu.
  4. Il est peu probable que l'affectation Performancewise soit plus lente que std::copy, Car les responsables de la mise en œuvre utiliseraient probablement std::copy En interne, si cela apportait un bénéfice de performance.

En conclusion, std::copy Est moins expressif, peut ne pas être correct et n'est pas encore plus rapide. Donc, il n'y a pas vraiment de raison de l'utiliser ici.

64
Grizzly

L'invocation de std::copy peut essayer d’accéder aux éléments situés au-delà de la fin du vecteur de destination.

Utilisez l'affectation.

Ce n'est pas à vous de faire de la micro-optimisation: c'est la responsabilité de l'auteur de la bibliothèque, et finalement celle du compilateur.

Vous pouvez faire votre code arbitrairement rapide s'il n'a pas à être correct.

Dans le cas de copy, cependant, il est plutôt douteux que ce soit même plus rapide, et ce n'est certainement pas correct pour le cas général.

10
Cheers and hth. - Alf

Si v2 _ n'est pas assez grand, vous obtiendrez un dépassement de tampon si vous utilisez copy comme vous l'avez déjà fait.

Vous pouvez utiliser un itérateur à insertion arrière qui appellera Push_back on v2. Toutefois, cela pourrait entraîner de multiples réaffectations, selon la taille de v1 est.

copy(v1.begin(), v1.end(), back_inserter(v2));

Vous feriez mieux de laisser vector gérer les choses correctement. L'opérateur d'affectation effectue cette opération, de même que vector::assign:

v2.assign(v1.begin(), v1.end());

J'ai la moindre idée que l'opérateur d'affectation est implémenté en termes de vector::assign.

9
Peter Wood

C'est plus court.

std::copy est principalement destiné à la copie de sections de conteneurs. Si vous devez copier un conteneur entier, vous pouvez également utiliser le constructeur de copie.

2
Symaxion

Cession, de loin. Plus généralement, chaque fois que la taille du vecteur peut changer, ou changer tout le contenu du vecteur, vous devriez préférer les fonctions membres. La seule fois std::copy serait approprié si vous ne remplacez qu'une petite plage totalement dans le vecteur.

2
James Kanze

L'affectation est plus claire et utilise en interne std::copy (Ou unitizalized_copy_M_allocate_and_copy En fonction de la taille et de la capacité) ou les performances sont identiques.

1
FredericS