Réserve de vecteur STL () et copie ()

Salutations,

J’essaie d’effectuer une copie d’un vecteur (vec1) vers un autre (vec2) en utilisant les 2 lignes de code abrégées suivantes (l’application de test complète suit):

vec2.reserve( vec1.size() ); copy(vec1.begin(), vec1.end(), vec2.begin()); 

Alors que l’appel à vec2 définit la capacité du vecteur vec2, la copie de données dans vec2 ne semble pas renseigner les valeurs de vec1 à vec2.

Le remplacement de la fonction copy () par des appels à push_back () fonctionne comme prévu.

Qu’est-ce que j’oublie ici?

Merci de votre aide. Le programme de test vectest.cpp suivi de la sortie résultante suit.

Compilateur: gcc 3.4.4 sur cygwin.

Nat

 /** * vectest.cpp */ #include  #include  using namespace std; int main() { vector vec1; vector vec2; vec1.push_back(1); vec1.push_back(2); vec1.push_back(3); vec1.push_back(4); vec1.push_back(5); vec1.push_back(6); vec1.push_back(7); vec2.reserve( vec1.size() ); copy(vec1.begin(), vec1.end(), vec2.begin()); cout << "vec1.size() = " << vec1.size() << endl; cout << "vec1.capacity() = " << vec1.capacity() << endl; cout << "vec1: "; for( vector::const_iterator iter = vec1.begin(); iter < vec1.end(); ++iter ) { cout << *iter << " "; } cout << endl; cout << "vec2.size() = " << vec2.size() << endl; cout << "vec2.capacity() = " << vec2.capacity() << endl; cout << "vec2: "; for( vector::const_iterator iter = vec2.begin(); iter < vec2.end(); ++iter ) { cout << *iter << endl; } cout << endl; } 

sortie:

 vec1.size() = 7 vec1.capacity() = 8 vec1: 1 2 3 4 5 6 7 vec2.size() = 0 vec2.capacity() = 7 vec2: 

Comme indiqué dans d’autres réponses et commentaires, vous devez simplement utiliser la fonctionnalité intégrée de vector pour cela. Mais:

Lorsque vous reserve() éléments reserve() , le vecteur allouera suffisamment d’espace pour (au moins?) Autant d’éléments. Les éléments n’existent pas dans le vecteur, mais la mémoire est prête à être utilisée. Cela accélérera éventuellement push_back() car la mémoire est déjà allouée.

Lorsque vous resize() le vecteur, il allouera suffisamment d’espace à ces éléments, mais les appenda également au vecteur .

Ainsi, si vous redimensionnez un vecteur à 100, vous pourrez accéder aux éléments 0 à 99, mais si vous réservez 100 éléments, ils ne sont pas encore insérés, ils sont juste prêts à être utilisés.

Ce que vous voulez, c’est quelque chose comme ça:

 vec2.reserve( vec1.size() ); copy(vec1.begin(), vec1.end(), std::back_inserter(vec2)); 

std::back_inserter est défini dans

Si les vecteurs sont du même type, utilisez la construction de copie ou l’affectation de copie:

 vec2(vec1); vec2 = vec1; 

Si les vecteurs ne sont pas exactement les mêmes (peut-être un allocateur différent ou quelque chose du genre, ou vec1 est un deque), vous voulez vraiment un constructeur basé sur une plage ou une affectation basée sur une plage:

 vec2(vec1.begin(), vec1.end()); // range-based constructor vec2.assign(vec1.begin(), vec1.end()); // range-based assignment 

Si vous insistez pour le faire avec std::copy , la méthode appropriée est la suivante:

 copy(vec1.begin(), vec1.end(), back_inserter(vec2)); 

Depuis la réservation de l’espace ne le rend pas assignable. copy fonctionne en assignant chaque élément à sa nouvelle valeur. Donc, vec2.size() doit être au moins aussi grand que vec1.size() dans votre cas. L’appel de reserve ne modifie pas réellement la taille d’un vecteur, mais simplement sa capacité.

Dans le livre Effective STL , Scott Meyers affirme que presque toutes les utilisations de std :: copy pour l’insertion doivent être remplacées par des fonctions de membre basées sur des plages. Je vous suggère d’en prendre un exemplaire, c’est une excellente référence!

Pourquoi pas: vec2 = vec1; ?

Changer la réserve pour redimensionner ():

 vec2.resize(vec1.size(), '\0'); copy(vec1.begin(), vec1.end(), vec2.begin()); 

Je crois que c’est la solution dont vous avez besoin.

Je ne peux pas vous donner une très bonne description de la différence, mais fondamentalement reserve () s’assure que vous disposez de suffisamment d’espace, et resize () insère en fait quelque chose.

À mon avis, la méthode la plus simple consiste à utiliser la méthode std :: vector :: insert:

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

(voir http://www.sgi.com/tech/stl/Vector.html )