2011-11-09 4 views
13

W jaki sposób należy używać wartości value_std?
próbowałem go używać tak:Przy użyciu parametru o typie szablonu

#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(); 
} 

Ale to skutkuje:

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’ 

Myślałem, że to, co było dla :: VALUE_TYPE?

+0

możliwy duplikat [Gdzie i dlaczego muszę wstawić słowa kluczowe "szablon" i "typename"?] (Http://stackoverflow.com/questions/610245/where-and-why-do-i-have -to-put-the-template-and-nazwa-listy-słów kluczowych) –

+1

Podczas pisania kodu biblioteki wielokrotnego użytku (lub nawet, zawsze) wskazane jest również, aby nie używać 'use namespace std;'. Po prostu przeliteruj właściwą przestrzeń nazw. –

+0

@KerrekSB: To był przykład. –

Odpowiedz

21

Musisz użyć typename:

typename T::value_type pop() 

i tak dalej.

Powód jest taki, że kompilator nie może wiedzieć, czy T :: typ_wartości jest typem zmiennej składowej (nikt nie utrudnia zdefiniowania typu struct X { int value_type; }; i przekazuje go do szablonu). Jednak bez tej funkcji nie można przeanalizować kodu (ponieważ znaczenie konstruktów zmienia się w zależności od tego, czy jakiś identyfikator oznacza typ lub zmienną, np. T * p może być deklaracją mnożenia lub deklaracji). Dlatego reguła jest taka, że ​​wszystko, co może być typu lub zmiennej i nie jest jawnie oznaczone jako typ przez prefiksowanie go z typename, jest uważane za zmienną.

+0

Dzięki za wyjaśnienie! –

+0

@ Jonathan: Aby uzyskać dodatkowe wyjaśnienia, zobacz także ten FAQ: [Do czego służy słowo kluczowe 'typename'?] (Http://www.comeaucomputing.com/techtalk/templates/#typename) – ildjarn

7

Użyj słowa kluczowego typename, aby wskazać, że to naprawdę typ.

void push(typename T::value_type& item) 

typename T::value_type pop()