2011-02-03 10 views
7

Ahh, C++ template ...Qual è il significato di questo errore 'mancare argomenti modello' C++

The code I see,
makes sense to me,
but GCC...
it disagrees.

Il seguente codice compilato ed eseguito come previsto, ma se si rimuove il commento che #define, si ottiene l'errore , che non capisco. Il simbolo iterator ha ancora una sola cosa a cui può riferirsi: il typedef nella superclasse. Quindi immagino di avere due domande: 1. Che cosa significano gli errori? 2. Qual è il modo migliore per risolverli.

#include <map> 
#include <string> 
#include <cstdio> 

using namespace std; 

// #define WITH_TEMPLATE 1 

#ifdef WITH_TEMPLATE 
template <class C> 
struct MyClass : public map<string, C> 
#else 
struct MyClass : public map<string, int> 
#endif 
{ 
    bool haskey(const string &s) 
    { 
     iterator it = find(s); 
     return (it != end()); 
    } 
}; 

int main() 
{ 
#ifdef WITH_TEMPLATE 
    MyClass<int> m; 
#else 
    MyClass m; 
#endif 
    m["test"] = 10;  
    printf("%d %d\n", m.haskey("test"), m.haskey("no")); 
} 

Errori da GCC:

temp.cc: In member function ‘bool MyClass::haskey(const std::string&)’:
temp.cc:18: error: missing template arguments before ‘it’
temp.cc:18: error: expected `;' before ‘it’
temp.cc:19: error: ‘it’ was not declared in this scope
temp.cc:19: error: there are no arguments to ‘end’ that depend on a template parameter, so a declaration of ‘end’ must be available
temp.cc:19: error: (if you use ‘-fpermissive’, G++ will accept your code, but allowing the use of an undeclared name is deprecated)

+0

Hai provato stringa :: iterator? – Lordalcol

risposta

4

È necessario modificare le vostre MyClass :: metodo Haskey troppo.

bool haskey(const string &s) 
{ 
    typename MyClass<C>::iterator it = this->find(s); 
    return (it != this->end()); 
} 

spiegazione di un tale comportamento è nella sezione "Nome di ricerca, modelli, e l'accesso a membri di classi base" a http://physics.ucsd.edu/students/courses/winter2008/physics141/manuals/rhel-gcc-en-4/c---misunderstandings.html (link dal commento di un'altra risposta, nel caso).

intero codice di esempio fisso: http://ideone.com/G7Rty

+1

Grazie. Contrassegnerei questo come risposta, ma non spiega il motivo dell'errore. Questa spiegazione è in un link nell'altra risposta. –

+0

Questo link è rotto o dietro un paywall. Qualsiasi riferimento aggiornato? –

3
iterator it = find(s); 
return (it != end()); 

Questa linea dovrebbe essere il più,

#ifdef WITH_TEMPLATE 
      typename map<string, C>::iterator it = this->find(s); 
      return (it != this->end()); 
#else 
      map<string, int>::iterator it = find(s); 
      return (it != end()); 
#endif 
+1

Hai dimenticato 'typename'. –

+0

@Nawaz la classe derivata non può vedere i typedef della classe base? – UmmaGumma

+0

@Ashot: quando la classe base è un modello, il compilatore non può sapere in fase di analisi se la classe contiene o meno il typedef o meno. Quindi, è necessario utilizzare typename in modo esplicito per i tipi di riferimento. – Puppy