2017-10-16 15 views
1

Je me demande comment aller sur la copie de certains éléments d'un vecteur donné dans l'autre.Comment copier dans un vecteur non initialisé?

std::vector<T> vec2; 
vec2.reserve(N); 
std::copy_if(vec1.begin(), 
      vec1.end(), 
      vec2.begin(), 
      [=](const T& r) { 
      return /*something*/ 
}); 

(À ce stade vec1 a un tas d'éléments déjà.)

Ou devrais-je utiliser back_inserter?

std::vector<T> vec2; 
vec2.reserve(N); 
std::copy_if(vec1.begin(), 
      vec1.end(), 
      std::back_inserter(vec2), 
      [=](const T& r) { 
      return /*something*/ 
}); 

Lequel de ces éléments fonctionnerait, si non? Aussi, l'appel à réservation est-il nécessaire?

+1

Vous devez utiliser 'back_inserter' –

+0

Pourquoi le premier ne fonctionne-t-il pas? @IgorTandetnik – Dovahkiin

+1

@Dovahkiin Il n'a pas d'éléments encore où vous allez copier. –

Répondre

1

La première solution est incorrecte parce reserve ne pas ajouter des éléments à votre vecteur (il ne réserve que la mémoire que vous ne pouvez pas utiliser). copy_if requiert que l'itérateur de sortie soit valide et pointe vers le début d'une séquence capable de contenir tous les éléments que vous voulez copier alors que votre vecteur après avoir appelé reserve ne peut pas contenir les valeurs car il n'a que de la mémoire brute non initialisée donc begin retourne effectivement un itérateur à la fin. Si vous copiez des éléments de cette façon, le vecteur ne connaîtra pas l'initialisation de ces éléments, ce qui entraîne beaucoup de problèmes.
D'autre part, la deuxième solution est bien. back_inserter insère des éléments à vecteur (qui est plus que la mémoire juste allocation) de sorte que le vecteur est au courant de ce qui se passe. Notez que l'appel reserve ne change rien dans l'aspect de la justesse de ce code. Je veux dire qu'il pourrait être omis et le code fonctionnerait très bien. Cependant, il peut être judicieux de le laisser là surtout si vous savez combien d'éléments (même si ce n'est qu'une approximation) que vous allez insérer. Cela va réduire le nombre d'allocations dynamiques ce qui est bon pour la performance.