std::vector<T,Allocator>:: reserve
|
void
reserve
(
size_type new_cap
)
;
|
(constexpr depuis C++20) | |
Augmente la capacité du vecteur (le nombre total d'éléments que le vecteur peut contenir sans nécessiter de réallocation) à une valeur supérieure ou égale à new_cap . Si new_cap est supérieur à la capacity() actuelle, un nouveau stockage est alloué, sinon la fonction ne fait rien.
reserve()
ne modifie pas la taille du vecteur.
Si
new_cap
est supérieur à
capacity()
, tous les itérateurs (y compris l'itérateur
end()
) et toutes les références aux éléments sont invalidés. Sinon, aucun itérateur ou référence n'est invalidé.
Après un appel à
reserve()
, les insertions ne déclencheront pas de réallocation sauf si l'insertion rendrait la taille du vecteur supérieure à la valeur de
capacity()
.
Table des matières |
Paramètres
| new_cap | - | nouvelle capacité du vecteur, en nombre d'éléments |
| Exigences de type | ||
-
T
doit satisfaire aux exigences de
MoveInsertable
dans
*
this
.
(depuis C++11)
|
||
Valeur de retour
(aucun)
Exceptions
- std::length_error si new_cap > max_size ( ) .
-
Toute exception levée par
Allocator::allocate()(typiquement std::bad_alloc ).
Si une exception est levée, cette fonction n'a aucun effet ( strong exception guarantee ).
|
Si le constructeur de déplacement de
|
(depuis C++11) |
Complexité
Au plus linéaire en la size() du conteneur.
Notes
Utiliser correctement
reserve()
peut éviter des réallocations inutiles, mais des utilisations inappropriées de
reserve()
(par exemple, l'appeler avant chaque
push_back()
) peuvent en réalité augmenter le nombre de réallocations (en provoquant une croissance linéaire plutôt qu'exponentielle de la capacité) et entraîner une complexité computationnelle accrue ainsi qu'une diminution des performances. Par exemple, une fonction qui reçoit un vecteur arbitraire par référence et y ajoute des éléments ne devrait généralement
pas
appeler
reserve()
sur le vecteur, car elle ne connaît pas les caractéristiques d'utilisation du vecteur.
Lors de l'insertion d'une plage, la version de plage de
insert()
est généralement préférable car elle préserve le comportement correct de croissance de la capacité, contrairement à
reserve()
suivi d'une série d'appels
push_back()
.
reserve()
ne peut pas être utilisé pour réduire la capacité du conteneur ; à cette fin,
shrink_to_fit()
est fourni.
Exemple
#include <cstddef> #include <iostream> #include <new> #include <vector> // minimal C++11 allocator with debug output template<class Tp> struct NAlloc { typedef Tp value_type; NAlloc() = default; template<class T> NAlloc(const NAlloc<T>&) {} Tp* allocate(std::size_t n) { n *= sizeof(Tp); Tp* p = static_cast<Tp*>(::operator new(n)); std::cout << "allocating " << n << " bytes @ " << p << '\n'; return p; } void deallocate(Tp* p, std::size_t n) { std::cout << "deallocating " << n * sizeof *p << " bytes @ " << p << "\n\n"; ::operator delete(p); } }; template<class T, class U> bool operator==(const NAlloc<T>&, const NAlloc<U>&) { return true; } template<class T, class U> bool operator!=(const NAlloc<T>&, const NAlloc<U>&) { return false; } int main() { constexpr int max_elements = 32; std::cout << "using reserve: \n"; { std::vector<int, NAlloc<int>> v1; v1.reserve(max_elements); // reserves at least max_elements * sizeof(int) bytes for (int n = 0; n < max_elements; ++n) v1.push_back(n); } std::cout << "not using reserve: \n"; { std::vector<int, NAlloc<int>> v1; for (int n = 0; n < max_elements; ++n) { if (v1.size() == v1.capacity()) std::cout << "size() == capacity() == " << v1.size() << '\n'; v1.push_back(n); } } }
Sortie possible :
using reserve: allocating 128 bytes @ 0xa6f840 deallocating 128 bytes @ 0xa6f840 not using reserve: size() == capacity() == 0 allocating 4 bytes @ 0xa6f840 size() == capacity() == 1 allocating 8 bytes @ 0xa6f860 deallocating 4 bytes @ 0xa6f840 size() == capacity() == 2 allocating 16 bytes @ 0xa6f840 deallocating 8 bytes @ 0xa6f860 size() == capacity() == 4 allocating 32 bytes @ 0xa6f880 deallocating 16 bytes @ 0xa6f840 size() == capacity() == 8 allocating 64 bytes @ 0xa6f8b0 deallocating 32 bytes @ 0xa6f880 size() == capacity() == 16 allocating 128 bytes @ 0xa6f900 deallocating 64 bytes @ 0xa6f8b0 deallocating 128 bytes @ 0xa6f900
Rapports de défauts
Les rapports de défauts modifiant le comportement suivants ont été appliqués rétroactivement aux normes C++ précédemment publiées.
| DR | S'applique à | Comportement publié | Comportement corrigé |
|---|---|---|---|
| LWG 329 | C++98 |
une réallocation pouvait être déclenchée si une insertion
rendait la taille du vecteur supérieure à la taille spécifiée dans l'appel le plus récent à
reserve()
|
déclenchée uniquement si la taille
du vecteur devient supérieure à capacity() |
| LWG 2033 | C++11 |
T
n'était pas requis d'être
MoveInsertable
|
requis |
Voir aussi
|
renvoie le nombre d'éléments pouvant être contenus dans le stockage actuellement alloué
(fonction membre publique) |
|
|
renvoie le nombre maximum possible d'éléments
(fonction membre publique) |
|
|
modifie le nombre d'éléments stockés
(fonction membre publique) |
|
|
(
DR*
)
|
réduit l'utilisation de la mémoire en libérant la mémoire inutilisée
(fonction membre publique) |