Error de simbolo externo sin resolver (MSVS)

Iniciado por digimikeh, 7 Marzo 2019, 03:54 AM

0 Miembros y 1 Visitante están viendo este tema.

digimikeh

Hola amigos..

Estoy estudiando templates y no comprendo este comportamiento:

A continuacion la forma en que NO funciona (con esta forma obtengo el error que sale en el titulo)

Código (cpp) [Seleccionar]

//Clase.h

template <class TM>
class Clase{

    TM num1, num2;

public:
    Clase(TM n1, TM n2);
    TM ObtenerMultiplicacion() const;

};



Código (cpp) [Seleccionar]

//Clase.cpp

#include "Clase.h"

template <class TM>
Clase<TM>::Clase(TM n1, TM n2){
    this->num1 = n1;
    this->num2 = n2;
}


template <class TM>
TM Clase<TM>::ObtenerMultiplicacion() const{
    return this->num1 * this->num2;
}



Sin embargo, con esta forma SI que funciona:
Código (cpp) [Seleccionar]

//Clase.h

template <class TM>
class Clase{

    TM num1, num2;

public:
    Clase(TM n1, TM n2);
    TM ObtenerMultiplicacion() const;

};

template <class TM>
Clase<TM>::Clase(TM n1, TM n2){
    this->num1 = n1;
    this->num2 = n2;
}


template <class TM>
TM Clase<TM>::ObtenerMultiplicacion() const{
    return this->num1 * this->num2;
}


Como verán, declarar la clase y definir sus miembros dentro del mismo archivo me funciona, pero si lo separo, no va... y me parece extraño, porque en el archivo Clase.cpp estoy incluyendo la cabecera con #include "Clase.h"

Que ha sucedido??


gracias de antemano.






Dungeons & dragons;
dragons.Attack();

digimikeh

Ya entendí, me autorespondo por si alguien mas le interesa la razón..

Pasa que las funciones de clases que usen plantilla son siempre inline, es decir se deben declarar y definir dentro de la clase o al menos en el mismo archivo, creo que a este punto la extensión adecuada del archivo sería .hpp


Dungeons & dragons;
dragons.Attack();

K-YreX

Como bien dices tiene que estar todo en el mismo fichero (o al menos que lo parezca). Para estos casos se suele usar la extensión <hpp> pero simplemente para ver más rápidamente a qué está haciendo referencia (pero si se usa <cpp> también funcionaría).
Para no tenerlo todo en el mismo fichero se suele crear la clase en el <clase.h> y las funciones miembro se implementan en <clase.hpp> y se incluye el <clase.hpp> dentro del <clase.h> en vez de al revés. Entonces como en el <main> incluimos <clase.h>, ya estaríamos incluyendo todo.
Código (cpp) [Seleccionar]

// clase.h
#ifndef CLASE_H // opcional
#define CLASE_H // opcional
class Clase{

};

#include "clase.hpp"
#endif // opcional
Código (cpp) [Seleccionar]

cout << "Todos tenemos un defecto, un error en nuestro código" << endl;

digimikeh

seria como una llamada anidada de archivos.. verdad?

main llama a Clase.h y ésta llama a Clase.hpp ?

Saludos...!"
Dungeons & dragons;
dragons.Attack();

K-YreX

Más o menos eso es.
Cuando haces un <#include fichero> al fin y al cabo es como si pegaras todo el contenido de <fichero> justo en la línea donde está el <include>. Entonces esto te permite implementarlo en distintos ficheros pero para la máquina a la hora de compilar es como si estuviera todo en el mismo. Es una forma de poder mantener la estructura de mantener las implementaciones en un fichero diferente a las declaraciones.
Código (cpp) [Seleccionar]

cout << "Todos tenemos un defecto, un error en nuestro código" << endl;