2012-04-21 21 views
16

Me doy cuenta de que se me han hecho preguntas similares anteriormente, pero leí algunas y aún no veo dónde me estoy equivocando. Cuando simplemente escribo mi clase sin separar el prototipo de la definición, todo funciona bien. El problema ocurre cuando se separo el prototipo y definición como se muestra a continuación:"usado sin parámetros de plantilla"

template<class T> class VisitedSet { 
public: 
    VisitedSet(); 
    int getSize(); 
    void addSolution(const T& soln); 
    void evaluate(); 
private: 
    vector<T> vec; 
    int iteration; 
}; 

Y como un ejemplo de una definición que me da este error:

int VisitedSet::getSize() { 
    return vec.size(); 

nunca he hecho una clase de plantilla antes , por favor, perdónenme si el problema aquí es trivial.

+0

Nota: En la mayoría de los casos, desea que las definiciones de las funciones miembro de la plantilla estén accesibles en el encabezado. Si las definiciones están en el encabezado, recuerde marcarlas como 'en línea' (o defínalos dentro de la definición de clase de plantilla), si no lo son, piense dos veces y asegúrese de que no necesita las definiciones en el encabezado (lo hace no necesita las definiciones en un encabezado si crea una instancia explícita en la unidad de traducción que contiene la definición para * todos * tipos con los que desea utilizar la plantilla). Me temo que vas a obtener algo de esto muy pronto ... –

Respuesta

28

VisitedSet es una plantilla, no una clase, por lo que no se puede utilizar en un nombre VisitedSet especificador anidada tales como VisitedSet::getSize(). Del mismo modo que ha especificado la declaración de class VisitedSet<T> para todos class T, debe especificar la definición de VisitedSet<T>::getSize() para todos class T:

template<class T> 
int VisitedSet<T>::getSize() { 
//   ^^^ 
    return vec.size(); 
} 

El nombre de una plantilla puede, sin embargo, ser utilizado como si se tratara de una clase dentro una definición de plantilla:

template<class T> 
struct Example { 
    Example* parent; 
    T x, y; 
}; 

En este caso, es la abreviatura de ExampleExample<T>.

0

trate de poner

template <typename T> 

por encima de la implementación de VisitedSet :: getSize() - pero ten en cuenta que, en general, las clases y funciones de plantilla todos deben ser entre líneas. Consulte C++ faq here para obtener más información.

+0

cuando puse la 'plantilla ' inmediatamente encima de la línea con 'int VisitedSet :: getSize() {', obtengo precisamente el mismo error. ¿Se prefiere que ** no ** separe el prototipo de la definición? ¿Es eso lo que significa inlinear en este contexto? – synaptik

+0

@synaptic También necesita usar el argumento de la plantilla en la clase como yo he sugerido en las otras respuestas. –

3

desea que esta:

template <class T> 
int VisitedSet<T>::getSize() { 
    return vec.size(); 
} 
2

Hay que indicar el parámetro de plantilla en la definición, así

template<class T> 
int VisitedSet<T>::getSize() { 
    return vec.size(); 
} 

de lo contrario el compilador puede no coincidir con la declaración. Por ejemplo, podría haber especializaciones para algunos tipos de parámetros.

+0

Ya veo. Gracias a todos. – synaptik

2

Hay que dejar que el compilador sabe que va a implementar un método en función de plantilla:

template<typename T> 
int VisitedSet<T>::getSize() { 
    return vec.size(); 
} 
Cuestiones relacionadas