2011-11-09 13 views
13

Come si suppone di utilizzare un valore_type di un contenitore std?
Ho cercato di usare in questo modo:Utilizzo del parametro value_type di un parametro

#include <vector> 

using namespace std; 

template <typename T> 
class TSContainer { 
private: 
     T container; 
public: 
     void push(T::value_type& item) 
     { 
       container.push_back(item); 
     } 
     T::value_type pop() 
     { 
       T::value_type item = container.pop_front(); 
       return item; 
     } 
}; 
int main() 
{ 
     int i = 1; 
     TSContainer<vector<int> > tsc; 
     tsc.push(i); 
     int v = tsc.pop(); 
} 

Ma questo si traduce in:

prog.cpp:10: error: ‘T::value_type’ is not a type 
prog.cpp:14: error: type ‘T’ is not derived from type ‘TSContainer<T>’ 
prog.cpp:14: error: expected ‘;’ before ‘pop’ 
prog.cpp:19: error: expected `;' before ‘}’ token 
prog.cpp: In function ‘int main()’: 
prog.cpp:25: error: ‘class TSContainer<std::vector<int, std::allocator<int> > >’ has no member named ‘pop’ 
prog.cpp:25: warning: unused variable ‘v’ 

Ho pensato che questo era quello che :: value_type è stato per?

+0

possibile duplicato di [Dove e perché devo inserire le parole chiave "template" e "typename"?] (Http://stackoverflow.com/questions/610245/where-and-why-do-i-have -to-put-the-template-and-typename-keywords) –

+1

Quando scrivi un codice di libreria riutilizzabile (o anche, mai) è anche consigliabile non usare 'using namespace std;'. Spiega semplicemente lo spazio dei nomi corretto. –

+0

@KerrekSB: è stato un esempio. –

risposta

21

devi usare typename:

typename T::value_type pop() 

e così via.

Il motivo è che il compilatore non può sapere se T :: value_type è un tipo di variabile membro (nessuno impedisce di definire un tipo struct X { int value_type; }; e passarlo al modello). Tuttavia senza questa funzione, il codice non può essere analizzato (poiché il significato dei costrutti cambia a seconda che qualche identificatore designi un tipo o una variabile, ad esempio T * p può essere una moltiplicazione o una dichiarazione puntatore). Pertanto, la regola è che tutto ciò che può essere di tipo o variabile e non è esplicitamente contrassegnato come tipo con il prefisso typename è considerato una variabile.

+0

Grazie per la spiegazione! –

+0

@Jonathan: per ulteriori spiegazioni, vedere anche queste domande frequenti: [Qual è la parola chiave 'typename' usata per?] (Http://www.comeaucomputing.com/techtalk/templates/#typename) – ildjarn

7

Utilizzare la parola chiave typename per indicare che si tratta di un tipo realmente.

void push(typename T::value_type& item) 

typename T::value_type pop() 
Problemi correlati