Si quiero establecer la capacidad de un std::vector
tengo que llamar .reserve(...)
, ¿hay alguna razón por la que no es un argumento en el constructor de la capacidad de los contenedores de STL, std::string
, std::vector
?¿Por qué no hay argumento de capacidad en los constructores para los contenedores?
Respuesta
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.
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). –
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. –
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. –
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);
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
@ 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. –
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
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
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. –
Si el contructer es lento, crea un constructor foo en tu clase que solo reserve memoria –
- 1. ¿Por qué no se pueden sincronizar los constructores de Java?
- 2. deducción del argumento de la plantilla para los constructores
- 3. ¿Por qué se prefieren los contenedores STL a los contenedores MFC?
- 4. ¿Por qué los constructores de copia no están "encadenados" como constructores o destructores predeterminados?
- 5. ¿Para qué sirven los constructores estáticos?
- 6. ¿Por qué estoy obligado a hacer referencia a los tipos en los constructores no utilizados?
- 7. ¿Por qué los subcontroles se inicializan antes que sus contenedores?
- 8. Funciones virtuales en constructores, ¿por qué los idiomas son diferentes?
- 9. por qué los contenedores asociativos no ordenados no usan allocator_traits <T> en C++ 0x
- 10. ¿Hay algún riesgo real derivado de los contenedores C++ STL?
- 11. ¿Qué son los constructores implícitos en Java
- 12. ¿Los constructores de Java no son públicos por defecto?
- 13. ¿Por qué Java no es compatible con la inferencia de tipos para los constructores?
- 14. comportamiento de los contenedores C++
- 15. ¿Los contenedores que pasan por valor invalidan los iteradores?
- 16. inferencia Genérico en los constructores
- 17. ¿Por qué no puedo establecer la capacidad inicial para un ConcurrentSkipListMap?
- 18. ¿Por qué los EJB son seguros y los servlets no?
- 19. ¿Por qué no hay sintaxis XPath para los nodos calificados de espacio de nombres?
- 20. ¿Cómo funcionan los constructores estáticos para los tipos genéricos?
- 21. ¿Por qué C no admite tipos genéricos implícitos en los constructores de clases?
- 22. ¿Por qué no hay funciones para generar eventos fuera de los no eventos en reactive-banana?
- 23. C++ Los constructores no tienen ningún tipo de devolución. ¿Exactamente por qué?
- 24. ¿Por qué se permite explícitamente a los constructores y constructores predeterminados con 2 o más parámetros (no predeterminados)?
- 25. ¿Forzar a los constructores de argumento único a ser explícitos en C++?
- 26. mejor opción para los contenedores de tipo fuerte en JavaScript
- 27. ¿Por qué los nombres de argumento de función no son importantes en las declaraciones de C++?
- 28. ¿Cómo copian los objetos STL los contenedores?
- 29. ¿Por qué los constructores enum no pueden ser protegidos o públicos en Java?
- 30. ¿Por qué no hay Dictionary.TrimExcess()?
vector tiene un constructor que toma un tamaño –