2011-05-14 2 views
1

J'essaie simplement de déclarer une carte iterator mais je reçois une erreur de compilation en disant « attendre, avant qu'il »Déclarer un iterator std :: carte provoque une erreur bizarre

je crois qu'il est parce que je ne l'ai pas inclus tout l'espace de noms std (using namespace std;) mais intentionnellement je ne veux pas tout inclure.

Mon code:

#include <map> 
#include <string> 

template <class Object> 
class Cont 
{ 
    public: 
     Cont() {} 
     Object* get(unsigned int nID) 
     { 
      std::map <unsigned int, Object*>::iterator it = m.begin(); // error here "expected ; before it" what is this error? 

      for (; it != m.end(); it++) 
      { 
       if ((*it).second->ID == nID) { return (*it).second; } 
      } 

      return NULL; 
     } 

     std::map <unsigned int, Object*> m; 
}; 

Je l'ai essayé aswell mais il ne fonctionne pas:

std::map <unsigned int, Object*>::std::iterator it = m.begin(); 
+0

Renvoyez-vous déclarer la classe 'Object' quelque part avant cette classe de modèle? Si non, alors c'est peut-être ce qui le cause. –

+0

Beaucoup de détail ici: http://stackoverflow.com/questions/610245/where-and-why-do-i-have-to-put-template-and-typename-on-dependent-names/613132#613132 –

Répondre

10

Si je ne me trompe pas parce que vous utilisez un argument template, vous devez préfixer la déclaration de l'itérateur avec typename.

typename std::map <unsigned int, Object*>::iterator it = m.begin(); 
+2

J'ai trouvé cette [discussion] (http://pages.cs.wisc.edu/~driscoll/typename.html) de typename utile dans la compréhension pourquoi et quand typename mot-clé est nécessaire. – rlduffy

0

Vous ne dites pas ce compilateur que vous utilisez, mais juste en coupant et Coller cela dans un nouveau fichier, il compile bien dans VS2010. Vous n'avez pas besoin de using namespace std; certainement ....

(Et votre pli de mettre un autre std :: avant l'itérateur était créatif, mais n'est pas correct. :-) Vous spécifiez que le modèle de classe de carte est situé dans l'espace de noms std ::, et l'itérateur est un type imbriqué dans le modèle de la carte.)

+0

J'ai trouvé le problème. Je dois utiliser le typage std :: map ... J'utilise le compilateur de devC++ – user593747

1

Quels sont vos paramètres de compilation et de drapeau? J'ai été capable de construire cela OK.

// test.cpp : Defines the entry point for the console application. 
// 

#include "stdafx.h" 

#include <map> 
#include <string> 

class Foo 
{ 
public: 
    int ID; 
}; 

template <class Object> class Cont 
{ 
    public: 
     Cont() {} 
     Object* get(unsigned int nID) 
     { 
      std::map <unsigned int, Object*>::iterator it = m.begin(); // error here "expected ; before it" what is this error? 

      for (; it != m.end(); it++) 
      { 
       if ((*it).second->ID == nID) { return (*it).second; } 
      } 

      return NULL; 
     } 

     std::map <unsigned int, Object*> m; 
}; 

int _tmain(int argc, _TCHAR* argv[]) 
{ 
    Cont<Foo> c; 
    c.get(2); 
    return 0; 
} 
+2

Vous utilisez un compilateur MS qui ** parfois ** peut le comprendre de toute façon. Selon la norme, il devrait encore se plaindre du mot-clé manquant. –

+0

Ouais - J'ai déjà été mordu par le passé, mais je n'ai pas utilisé gcc récemment et je l'ai oublié. J'ai confirmé l'erreur et la résolution en utilisant le codepad: http://codepad.org/GSCVOVj1 - Il y a aussi un thread SO expliquant que le mot-clé typename est en train de désambiguïser l'utilisation de type vs valeur ici: http://stackoverflow.com/questions/1215055/pourquoi-est-l'utilisation-de-typedef-dans-ce-modèle-nécessaire - le plus utile à emporter de ceci est que c'est encore un autre avantage (en dehors de la lisibilité) d'utiliser un typedef pour vos itérateurs. – holtavolt

Questions connexes