std::vector<T,Allocator>:: reserve
|
void
reserve
(
size_type new_cap
)
;
|
(constexpr desde C++20) | |
Incrementa la capacidad del vector (el número total de elementos que el vector puede contener sin requerir reasignación) a un valor mayor o igual a new_cap . Si new_cap es mayor que la capacity() actual, se asigna nuevo almacenamiento; de lo contrario, la función no hace nada.
reserve()
no cambia el tamaño del vector.
Si
new_cap
es mayor que
capacity()
, todos los iteradores (incluyendo el iterador
end()
) y todas las referencias a los elementos quedan invalidados. De lo contrario, ningún iterador o referencia queda invalidado.
Después de una llamada a
reserve()
, las inserciones no activarán la reasignación a menos que la inserción haría que el tamaño del vector sea mayor que el valor de
capacity()
.
Contenidos |
Parámetros
| new_cap | - | nueva capacidad del vector, en número de elementos |
| Requisitos de tipo | ||
-
T
debe cumplir con los requisitos de
MoveInsertable
en
*
this
.
(desde C++11)
|
||
Valor de retorno
(ninguno)
Excepciones
- std::length_error si new_cap > max_size ( ) .
-
Cualquier excepción lanzada por
Allocator::allocate()(típicamente std::bad_alloc ).
Si se lanza una excepción, esta función no tiene efecto ( strong exception guarantee ).
|
Si el constructor de movimiento de
|
(desde C++11) |
Complejidad
Como máximo lineal en el size() del contenedor.
Notas
El uso correcto de
reserve()
puede prevenir reasignaciones innecesarias, pero usos inapropiados de
reserve()
(por ejemplo, llamarlo antes de cada
push_back()
) pueden realmente incrementar el número de reasignaciones (al hacer que la capacidad crezca linealmente en lugar de exponencialmente) y resultar en mayor complejidad computacional y menor rendimiento. Por ejemplo, una función que recibe un vector arbitrario por referencia y le añade elementos normalmente
no
debería llamar
reserve()
en el vector, ya que no conoce las características de uso del vector.
Al insertar un rango, la versión de rango de
insert()
generalmente es preferible ya que preserva el comportamiento correcto de crecimiento de capacidad, a diferencia de
reserve()
seguido por una serie de
push_back()
s.
reserve()
no puede utilizarse para reducir la capacidad del contenedor; para ese propósito
shrink_to_fit()
está disponible.
Ejemplo
#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); } } }
Salida posible:
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
Informes de defectos
Los siguientes informes de defectos que modifican el comportamiento se aplicaron retroactivamente a los estándares de C++ publicados anteriormente.
| DR | Se aplica a | Comportamiento publicado | Comportamiento correcto |
|---|---|---|---|
| LWG 329 | C++98 |
podría desencadenarse una reasignación si una inserción
hace que el tamaño del vector sea mayor que el tamaño especificado en la llamada más reciente a
reserve()
|
solo se desencadena si el tamaño
del vector se vuelve mayor que capacity() |
| LWG 2033 | C++11 |
T
no se requería que fuera
MoveInsertable
|
requerido |
Véase también
|
devuelve el número de elementos que pueden almacenarse en la memoria actualmente asignada
(función miembro pública) |
|
|
devuelve el número máximo posible de elementos
(función miembro pública) |
|
|
cambia el número de elementos almacenados
(función miembro pública) |
|
|
(
DR*
)
|
reduce el uso de memoria liberando memoria no utilizada
(función miembro pública) |