2011-03-11 12 views
7

¿Está bien inicializar un vector 2D como este (aquí todos los valores en un vectro 2D 5x4 se inicializan en 3)?¿Está bien usar constructores para inicializar un vector 2D como un trazo en C++?

std::vector<std::vector<int> > foo(5, std::vector<int>(4, 3)); 

Esto parece comportarse bien, pero en todas partes que se ven en la web de la gente parece recomendar inicializar un vector de este tipo con los bucles y push_back(). Al principio tenía miedo de que todas las filas aquí apuntaran al mismo vector, pero ese no parece ser el caso. ¿Me estoy perdiendo de algo?

Respuesta

10

Esto es perfectamente válida - Usted obtendrá un vector 2D ([5], 4 elementos) con cada elemento inicializado a 3.

Para la mayoría de los otros casos (por ejemplo, donde se desea que los valores diferentes en diferentes elementos) no puede usar ningún trazador de líneas único y, por lo tanto, necesita bucles.

3

Bueno, el código es válido y de hecho hace lo que usted quiere que haga (asumiendo que entendí su intención correctamente).

Sin embargo, hacerlo de esa manera es generalmente ineficiente (al menos en la versión actual del idioma/biblioteca). La inicialización anterior crea un vector temporal y luego inicializa sub-vectores individuales por copiando el original. Eso puede ser bastante ineficiente. Por esta razón, en muchos casos es preferible para construir el vector de nivel superior por sí mismo

std::vector<std::vector<int> > foo(5); 

y luego iterar sobre ella y construir sus sub-vectores individuales en el lugar haciendo algo como

foo[i].resize(4, 3); 
+1

El costo del enfoque de una línea es la construcción de un único vector interno temporal, por lo que no es ** muy ** ineficiente. – Erik

+1

@Erik: construcción * y * destrucción. Pero no solo eso. El costo también incluye el costo de inicialización mediante copia de vector a vector, en contraposición al costo de la copia de elemento a vector en caso de construcción en el lugar. Para los tipos primitivos, la diferencia es en realidad cualitativa. – AnT

+1

Tal como lo veo, la variante copy-ctor terminará en una serie de llamadas equivalentes a memcpy, mientras que los loops se evaluarán en una serie de llamadas equivalentes a memset. Al menos si el compilador está optimizando algo. Sí, memcpy podría considerarse más caro que memset, pero con los datos de origen supuestamente en caché y los datos de destino presumiblemente no, no creo que veas diferencias prácticas para este escenario. Si los vectores eran más grandes o contenían objetos complejos, seguro, para sus datos, preferir la legibilidad. Sin embargo, su punto es bastante válido, el copiador * puede * ser más ineficiente. – Erik

Cuestiones relacionadas