2011-04-26 14 views

Respuesta

13

Hay una razón obvia: ¿cómo sería un constructor de este tipo?

Todos los contenedores de secuencia ya tienen un constructor que se puede llamar con un único argumento entero. Ese constructor cambia el tamaño del contenedor para tener el número especificado de elementos.

Sí, podría agregar un segundo parámetro (como bool reserve_instead_of_resize) para poder usar este constructor tanto para el tamaño inicial como para las reservas iniciales, pero creo que el resultado final sería confuso.

+0

Podría tomar otro, diferente parámetro entero para el tamaño Reservados - excepto que entraría en conflicto con el diferente parámetro 'const T &' para el valor inicial en el caso donde 'T = size_t' (y podría confundirse con él en otros casos donde uno es convertible a otro). –

+1

Es cierto. También está la cuestión de la coherencia: la reserva solo tiene sentido para el vector, por lo que terminaríamos con otro constructor solo para vector. Creo que todos (o la mayoría) de los otros constructores son utilizables para todos los contenedores de secuencia (aunque la cadena tiene algunos constructores adicionales, también es un contenedor menos genérico). Por lo que vale, raramente uso reserva; en ocasiones es útil como una optimización, pero no lo suficiente, creo, para garantizar otro constructor. –

+2

De vez en cuando uso 'reserve' no como una optimización, sino para evitar los efectos semánticos de la reasignación: invalidación de iteradores e indicadores y la posibilidad de una excepción. Estoy de acuerdo en que no vale realmente un constructor, o más bien un conjunto completo de duplicados de los constructores existentes. En el peor de los casos, creo que quiere construir con contenidos no triviales y también reservar, y le asusta el costo de la reasignación. Entonces debe construir vacío, luego reservar, luego insertar los contenidos. –

10

Usted podría simplemente hacer una función para crear un vector reservados:

// make_reserved_vector 
template <typename... T> 
std::vector<T...> make_reserved_vector(size_t n) { 
    std::vector<T...> vec; 
    vec.reserve(n); 
    return vec; 
} 

y utilizar como:

auto myvec = make_reserved_vector<int>(32768); 
+4

Es una gran idea. Esto soluciona el problema, pero la biblioteca C++ todavía tiene un problema innato: puede que tenga que pagar por dos asignaciones de memoria (el primer constructor vectorial, cuando no tiene idea de cuál es la capacidad predeterminada), y luego el segundo (cuando reserva y posible desasignar y reasignar). Su solución saca lo mejor de esto, pero creo que el comité C++ necesita volver a abordar este problema. – rts1

+0

@ rts1: Exactamente, esa es mi preocupación también.Puede haber una "reserva de tamaño predeterminada" y luego otra reserva con la que llamamos. Podría haber múltiples constructores para eso, uno tomando el tamaño de la reserva. –

+1

bastante viejo q/a, pero en algún lugar tengo que liberar mi frustración;) No entiendo por qué al elegir entre la capacidad inicial y el tamaño inicial, eligen el tamaño. Si pudiéramos elegir la capacidad inicial, el tamaño podría cambiarse después de la construcción sin costo adicional. Tal como está ahora, o tengo que pedir un vector con un tamaño que tal vez no necesito o posiblemente no pague dos veces para obtener la capacidad que quiero. Imho eso es contra el primer principio de C++, no pagues por lo que no necesitas. De todos modos, su función es tal vez la mejor manera de lidiar con ella – user463035818

0

Para crear un vector, y especificando su capacidad en el mismo tiempo, crear una vector con la capacidad deseada, copie en ella los elementos que desee y borre del iterador devuelto por copia. Si el constructor es lento, simplemente escriba otro constructor con parámetros especiales que solo reserven memoria.

int main (int argc, char** argv) { 
    std::vector<size_t> v (10, 0); 
    size_t tmp [3] = {0, 1, 2}; 
    std::vector<size_t>::iterator i (v.begin()); 
    i = std::copy ((const size_t*)tmp, (const size_t*) &tmp [3], v.begin()); 
    v.erase (i, v.end()); 
    std::cout << "\tv capacity == " << v.capacity() << std::endl; 
} 

la Salida:

== v capacidad de 10

+0

Si los constructores de los elementos tienen efectos secundarios (o simplemente son lentos), entonces esto tiene un comportamiento diferente a la creación de un vector vacío y la reserva de cierta capacidad. –

+0

Si el contructer es lento, crea un constructor foo en tu clase que solo reserve memoria –

Cuestiones relacionadas