2011-11-09 9 views
13

¿Cómo se supone que use el value_type de un contenedor std?
traté de usarlo de esta manera:Utilizando el valor de un parámetro con plantilla value_type

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

Pero esto resulta en:

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’ 

pensé que esto era lo que era para :: value_type?

+0

posible duplicado de [¿Dónde y por qué tengo que poner las palabras clave "plantilla" y "nombre de tipo"?] (Http://stackoverflow.com/questions/610245/where-and-why-do-i-have -to-put-the-template-and-typename-keywords) –

+1

Cuando está escribiendo código de biblioteca reutilizable (o incluso, siempre) también es aconsejable no decir 'using namespace std;'. Simplemente deletrea el espacio de nombres correcto. –

+0

@KerrekSB: Fue un ejemplo. –

Respuesta

21

usted tiene que utilizar typename:

typename T::value_type pop() 

y así sucesivamente.

La razón es que el compilador no puede saber si T :: value_type es un tipo de variable miembro (nadie le impide definir un tipo struct X { int value_type; }; y pasarlo a la plantilla). Sin embargo, sin esa función, el código no se pudo analizar (porque el significado de construcciones cambia dependiendo de si algún identificador designa un tipo o una variable, por ejemplo, T * p puede ser una multiplicación o una declaración de puntero). Por lo tanto, la regla es que todo lo que pueda ser de tipo o variable y que no esté marcado explícitamente como tipo prefijándolo con typename se considera una variable.

+0

¡Gracias por la explicación! –

+0

@Jonathan: para obtener una explicación más detallada, consulte también esta pregunta frecuente: [¿Para qué sirve la palabra clave 'typename'?] (Http://www.comeaucomputing.com/techtalk/templates/#typename) – ildjarn

7

Use la palabra clave typename para indicar que es realmente un tipo.

void push(typename T::value_type& item) 

typename T::value_type pop() 
Cuestiones relacionadas