El otro día luchaba contra una construcción de C++ con la que no había tenido problemas antes. Estaba intentando iterar sobre un map del cual el segundo parámetro estaba templetizado.
Mi construcción era similar a tener:
map< string, vector<T*> > m;
Supongamos que escribimos una función que itera sobre este mapa, haciendo algo con los pares (string, vector):
template <typename T> void f() { map< string, vector<T*> > m; for (map< string, vector<T*> >::iterator it = m.begin(); it != m.end(); it++) { // hacer algo con las tuplas } }
Al momento de compilar, y muy para mi sorpresa, g++ reporta varios errores:
ejemplo.cpp: In function ‘void f()’: ejemplo.cpp:15: error: expected ‘;’ before ‘it’ ejemplo.cpp:16: error: ‘it’ was not declared in this scope ejemplo.cpp: In function ‘void f() [with T = std::basic_string<char, std::char_traits<char>, std::allocator<char> >]’: ejemplo.cpp:24: instantiated from here ejemplo.cpp:15: error: dependent-name ‘std::map::iterator’ is parsed as a non-type, but instantiation yields a type ejemplo.cpp:15: note: say ‘typename std::map::iterator’ if a type is meant
Aparentemente, y como nos indica g++ en su mensaje último de error, cuando tenemos un mapa templetizado, y queremos iterar sobre él, debemos agregar la keyword typename a la izquierda de la declaración del tipo de iterador, de la siguiente manera:
for (typename map< string, vector<T*> >::iterator it = m.begin(); it != m.end(); it++) { // hacer algo con las tuplas }
Realmente no lo tenía presente.
La nueva versión de C++, denominada C++0x, agregará la keyword auto, la cual indica al compilador que ha de inferir automaticamente el tipo de la variable asociada a partir del valor al cual se inicializa (similar al var de C#). auto permitirá evitar problemas de este estilo en el futuro, así como simplificar la lectura de código que ha de iterar sobre contenedores de la STL.
3 Responses to C++ Templates & Maps