2010-06-09 5 views
0

Je rencontre ce problème lors de l'écriture de mon propre HashTable. Tout fonctionne, mais quand j'essaye de modéliser la chose, ça me donne des erreurs. Je recréée le problème comme suit:C++ Utilisation d'un argument de modèle de classe en tant qu'argument de modèle pour un autre type

CE CODE WORKS:

typedef double Item; 

class A 
{ 
public: 
    A() 
    { 
     v.push_back(pair<string, Item>("hey", 5.0)); 
    } 

    void iterate() 
    { 
     for(Iterator iter = v.begin(); iter != v.end(); ++iter) 
      cout << iter->first << ", " << iter->second << endl; 
    } 

private: 
    vector<pair<string, double> > v; 
    typedef vector< pair<string, double> >::iterator Iterator; 
}; 

CE CODE NE PAS:

template<typename ValueType> 
class B 
{ 
public: 
    B(){} 

    void iterate() 
    { 
     for(Iterator iter = v.begin(); iter != v.end(); ++iter) 
      cout << iter->first << ", " << iter->second << endl; 
    } 

private: 
    vector<pair<string, ValueType> > v; 
    typedef vector< pair<string, ValueType> >::iterator Iterator; 
}; 

les messages d'erreur: g ++ -O0 -g3 -Wall -c -fmessage -longueur = 0 -omain.o .. \ main.cpp

.. \ main.cpp: 50: error: std::vector<std::pair<std::string, ValueType>, std::allocator<std::pair<std::string, ValueType> > >' is not derived from type Type B »

.. \ main.cpp: 50: erreur: ISO C++ interdit la déclaration de `itérateur 'sans type

.. \ main.cpp: 50: erreur: attendue`;' avant "Iterator"

.. \ main.cpp: Dans la fonction membre vide B :: itérer():

.. \ main.cpp: 44: Erreur: `Iterator 'n'a pas été déclarée dans cette portée

.. \ main.cpp: 44: erreur: attendu `; ' avant "iter"

.. \ main.cpp: 44: Erreur: `iter » n'a pas été déclarée dans ce champ

Quelqu'un sait-il pourquoi cela se passe? Merci!

Répondre

6

Ceci est appelé "noms dépendants" dans C++. Dans votre deuxième extrait de code, vous dites:

typedef vector< pair<string, ValueType> >::iterator Iterator; 

alors vous devriez dire:

typedef typename vector< pair<string, ValueType> >::iterator Iterator; 

Chaque fois que vous voyez une erreur « ne dérive pas ... », typename est à la rescousse. En général, l'idée est que le compilateur ne sait pas si iterator est un type ou d'une variable, parce qu'il ne sait pas ce que

vector< pair <string, ValueType> > 

est, car elle dépend de ValueType.

(Afraid Je ne suis pas en utilisant les bons termes, mais l'idée est correcte)

+0

devrait-il pas: typedef vecteur typename >: : itérateur de l'itérateur; ? – Tomek

+1

@Tomek: 'pair ' ne peut être qu'un type car 'pair' est un modèle de classe. Donc le compilateur sait que c'est un type et il n'est pas nécessaire de le désambiguïser avec 'typename'. – sth

+0

Tomek: ça marche très bien sans ça, donc je suppose que ça va. Vous ne dites pas par exemple paire :: first_type ici, donc vous n'avez pas besoin de ce nom de type. – iksemyonov

0

cela fonctionne grâce et prend tout son sens maintenant!

Et je ne veux pas utiliser un typedef, je peux aussi utiliser typename comme ceci:

for(typename list<pair<string, ValueType> >::const_iterator itr = v.begin(); itr != v.end() ; ++itr){ 
{ 
//code 
} 
+0

Vous feriez mieux de le typer, parce que c'est la bonne façon de faire les choses en général, et vous pourriez prendre l'habitude de ne pas typer les choses, ce qui ne serait pas très agréable) – iksemyonov

Questions connexes