program geeksforgeeks define container array c++ stl

c++ - geeksforgeeks - vector de la stl



STL like container typedef shortcut? (7)

C ++ 0x también ofrecerá un bucle for ranged, que es similar al iterativo para bucles en otros idiomas.

Desafortunadamente, GCC aún no implementa el rango para (pero implementa auto).

Editar: Mientras tanto, también considere typedefing el iterador. No evita el typedef de un solo uso (a menos que lo coloque en un encabezado, que siempre es una opción), pero hace que el código resultante sea más corto en un :: iterator.

Un patrón común con contenedores STL es este:

map<Key, Value> map; for(map<Key, Value>::iterator iter = map.begin(); iter != map.end(); ++iter) { ... }

Entonces, para evitar escribir la declaración de los parámetros de la plantilla, podemos hacer esto en alguna parte:

typedef map<Key, Value> TNiceNameForAMap;

Pero si este mapa solo se usa en una sola función o para una única iteración, esto es una sobrecarga molesta.

¿Hay alguna forma de evitar este tipodef?


En los últimos años, realmente he intentado alejarme del uso de loops escritos manualmente en lugar de usar los algoritmos STL. Su código anterior se puede cambiar a:

struct DoLoopBody { template <typename ValueType> inline void operator()(ValueType v) const { // ... } }; std::for_each (map.begin(), map.end(), DoLoopBody ());

Desafortunadamente, la clase DoLoopBody no puede ser una clase local, que a menudo se destaca como una desventaja. Sin embargo, veo esto como una ventaja en el hecho de que el cuerpo del bucle ahora se puede probar de forma aislada.


No estoy seguro de lo que quiere decir con "sobrecarga". Si simplifica la forma en que escribes tu código, úsala, de lo contrario mantente firme.

Si solo se usa en un ámbito restringido, coloque el typedef en ese mismo ámbito. Entonces no necesita ser publicado, documentado o aparecer en ningún diagrama UML. Por ejemplo (y no afirmo que este es el mejor código en otros aspectos):

int totalSize() { typedef std::map<Key, Value> DeDuplicator; DeDuplicator everything; // Run around the universe finding everything. If we encounter a key // more than once it''s only added once. // now compute the total int total = 0; for(DeDuplicator::iterator i = everything.begin(); i <= everything.end(); ++i) { total += i->second.size(); // yeah, yeah, overflow. Whatever. } return total; }

Combinando con la sugerencia de Ferruccio (si estás usando boost), el loop se convierte en:

BOOST_FOREACH(DeDuplicator::pair p, everything) { total += p.second.size(); }

Y combinando con la sugerencia de bk1e (si está usando C ++ 0x o tiene características de él), y suponiendo que BOOST_FOREACH interactúa con automático de la manera que creo que debería basarse en el hecho de que normalmente puede manejar conversiones implícitas a tipos compatibles :

std::map<Key, Value> everything; // snipped code to run around... int total = 0; BOOST_FOREACH(auto p, everything) { total += p.second.size(); }

No está mal.


Personalmente creo que MYMAP :: iterator es más legible que map <int, string> :: iterator o incluso std :: map <int, std :: string> :: iterator, así que siempre hago typedef. La única sobrecarga es una línea de código.

Una vez que se compila el código, no habrá diferencia en el tamaño o la velocidad del ejecutable. Solo se trata de la legibilidad.



Si typedef es local para una sola función, ni siquiera necesita ser un buen nombre. Usa X o MAP, como en una plantilla.


Una versión futura del estándar C ++ (conocido como C ++ 0x ) introducirá un nuevo uso para la palabra clave auto , que le permitirá escribir algo como lo siguiente:

map<Key, Value> map; for(auto iter = map.begin(); iter != map.end(); ++iter) { ... }