Existe-t-il un moyen de redimensionner un std::vector à une capacité inférieure lorsque je n'ai plus besoin de l'espace précédemment réservé ?
Réponses
Trop de publicités?STL efficace, par Scott Meyers, point 17 : utiliser la fonction swap
l'astuce pour réduire les capacités excédentaires.
vector<Person>(persons).swap(persons);
Après ça, persons
est "rétréci pour s'adapter".
Cela repose sur le fait que vector
Le constructeur de copie de l'utilisateur n'alloue que la quantité de mémoire nécessaire pour les éléments copiés.
Créez un nouveau vecteur, temporaire, à partir du vecteur existant, puis appelez la méthode swap sur le vecteur existant, en lui passant le vecteur temporaire. Laissez le temporaire (maintenant avec l'ancien tampon surdimensionné) sortir de la portée.
Hé presto, votre vecteur a exactement la bonne taille pour son contenu.
Si cela vous semble beaucoup de copies et d'allocations, gardez à l'esprit que c'est ce que fait le vecteur chaque fois qu'il doit réallouer au-delà de sa limite de réservation actuelle.
[Edit] Oui, je viens de dire la même chose que Sébastien en plus de mots. Encore un cas de stackoverflow race-condition ;-)
L'astuce du swap est un moyen efficace de réduire la capacité d'un objet, elle échange le contenu de mon vecteur avec un vecteur nouvellement créé par construction de copie :
vector<Person>(persons).swap(persons);
Notez qu'il n'y a aucune garantie que persons.capacity() ; après l'astuce du swap soit égal à la taille : la capacité de vector(persons) est la capacité que l'implémentation de la bibliothèque réserve aux vecteurs de taille persons.size().
Introduction de C++11 shrink_to_fit() .
shrink_to_fit() ainsi que l'astuce du swap ne garantissent pas que la taille de la capacité soit effectivement réduite à la taille du vecteur.
De toute façon, shrink_to_fit() peut invalider vos itérateurs (si une réallocation se produit) ou non : cela dépend de l'implémentation réelle de la bibliothèque.
Gardez à l'esprit que l'astuce de l'échange nécessite des constructions de copie de person.size() de Person et de person.size() destructions. Le shrink_to_fit() pourrait éviter toute cette copie et pourrait laisser vos itérateurs valides. Pourrait. Mais il se trouve que shrink_to_fit() est implémentée en termes de l'astuce du swap...
Vous cherchez un équivalent de QVector::squeeze et je crains qu'elle n'existe pas explicitement dans la STL. Choisissez la réponse de Sébastien si elle est correcte pour votre implémentation STL.