Programación General > C/C++

 undefined reference to 'nombre de funcion'

(1/1)

etchner:
Hola

Estaba practicando con el uso de plantillas en c++, y tengo el siguiente codigo

Fichero Conjunto.h

--- Código: Text ---     template <class TIPOP>    class posicion;         template <class TIPO>    class conjunto{    public:                 conjunto();                 conjunto(const conjunto &c);                 bool pertenece(TIPO elem) const;                 void insertar(TIPO elem);                 void borrar(TIPO elem);                      bool vacio(TIPO elem) const;                      posicion<TIPO> begin();                 posicion<TIPO> end();                      posicion<TIPO> siguiente(posicion<TIPO> posic);                 TIPO& elemento(posicion<TIPO> posic);                      const TIPO& elemento(posicion<TIPO> posic) const;                      TIPO& elemento(int posic);                      int getCardinalidad();         private:            void resize(int tam);                       TIPO* elementos;            int cardinalidad;               };         template <class TIPOP>    class posicion{            conjunto<TIPOP> subconjunto;            int indice;    }; 

Fichero Conjunto.cpp


--- Código: Text ---    #include<Conjunto.h>                         conjunto<TIPO>::conjunto(){}                         conjunto<TIPO>::conjunto(const conjunto<TIPO> &c){}         bool            conjunto<TIPO>::pertenece(TIPO elem) const{}         void            conjunto<TIPO>::insertar(TIPO elem){}         void            conjunto<TIPO>::borrar(TIPO elem){}         bool            conjunto<TIPO>::vacio(TIPO elem) const{}         posicion<TIPO>  conjunto<TIPO>::begin(){}         posicion<TIPO>  conjunto<TIPO>::end(){}         posicion<TIPO>  conjunto<TIPO>::siguiente(posicion<TIPO> posic){}         TIPO&           conjunto<TIPO>::elemento(posicion<TIPO> posic){}         TIPO&           conjunto<TIPO>::elemento(int posic){}         const TIPO&     conjunto<TIPO>::elemento(posicion<TIPO> posic) const{}  
Fichero usoConjunto.cpp

--- Código: Text ---     #include "Conjunto.h"         using namespace std;         conjunto<int> unionc(conjunto<int> c1, conjunto<int> c2){                 conjunto<int> nuevo;            for(int c = 0; c < c1.getCardinalidad(); c++){                    nuevo.insertar(c1.elemento(c));            }                 for (int a = 0; a < c2.getCardinalidad();a++){                    nuevo.insertar(c2.elemento(a));            }                 return nuevo;    }              int main(){} 
Al compilarlo con make, me da la siguiente salida:

usoConjunto.cpp:(.text+0x1b): undefined reference to `conjunto<int>::conjunto()'
usoConjunto.cpp:(.text+0x35): undefined reference to `conjunto<int>::elemento(int)'
usoConjunto.cpp:(.text+0x44): undefined reference to `conjunto<int>::insertar(int)'
usoConjunto.cpp:(.text+0x54): undefined reference to `conjunto<int>::getCardinalidad()'
usoConjunto.cpp:(.text+0x78): undefined reference to `conjunto<int>::elemento(int)'
usoConjunto.cpp:(.text+0x87): undefined reference to `conjunto<int>::insertar(int)'
usoConjunto.cpp:(.text+0x97): undefined reference to `conjunto<int>::getCardinalidad()'


He buscado por internet y por lo que veo hay un error al enlazar, pero no se como solucionarlo :S

alexg88:
Cuatro cosas:

1. Pon #include "Conjunto.cpp" al final del fichero Conjunto.h
2. Tienes que poner template <class TIPO> antes de cada  método en Conjunto.cpp para declarar que es una plantilla.
3. El #include <Conjunto.h> cambialo por #include "Conjunto.h"
4. La funciones getCardinalidad y resize no las defines en ninguna parte, tienes que definirlas.

Es importante que compiles sólo usoConjunto.cpp, porque Conjunto.cpp se compilará cuando Conjunto.h lo requiera, creando las métodos necesarios a partir de la plantilla.

Hay otra forma de hacerlo sin poner #include "Conjunto.cpp" en el fichero Conjunto.h, que es poner en el propio Conjunto.h las definiciones de los metodos directamente y entonces si lo compilarías de la manera normal (es decir, los métodos con plantilla los defines en Conjunto.h y los de sin plantilla en Conjunto.cpp).

Fichero Conjunto.h

--- Código: C++ ---      template <class TIPOP>    class posicion;         template <class TIPO>    class conjunto{    public:                 conjunto();                 conjunto(const conjunto &c);                 bool pertenece(TIPO elem) const;                 void insertar(TIPO elem);                 void borrar(TIPO elem);                      bool vacio(TIPO elem) const;                      posicion<TIPO> begin();                 posicion<TIPO> end();                      posicion<TIPO> siguiente(posicion<TIPO> posic);                 TIPO& elemento(posicion<TIPO> posic);                      const TIPO& elemento(posicion<TIPO> posic) const;                      TIPO& elemento(int posic);                      int getCardinalidad();         private:            void resize(int tam);                       TIPO* elementos;            int cardinalidad;               };         template <class TIPOP>    class posicion{            conjunto<TIPOP> subconjunto;            int indice;    }; #include "Conjunto.cpp"  
Fichero Conjunto.cpp



--- Código: C++ ---  template <class TIPO>  conjunto<TIPO>::conjunto(){}     template <class TIPO>                     conjunto<TIPO>::conjunto(const conjunto<TIPO> &c){}       template <class TIPO>   bool            conjunto<TIPO>::pertenece(TIPO elem) const{}      template <class TIPO>    void            conjunto<TIPO>::insertar(TIPO elem){}      template <class TIPO>    void            conjunto<TIPO>::borrar(TIPO elem){}      template <class TIPO>    bool            conjunto<TIPO>::vacio(TIPO elem) const{}      template <class TIPO>    posicion<TIPO>  conjunto<TIPO>::begin(){}      template <class TIPO>    posicion<TIPO>  conjunto<TIPO>::end(){}       template <class TIPO>   posicion<TIPO>  conjunto<TIPO>::siguiente(posicion<TIPO> posic){}       template <class TIPO>   TIPO&           conjunto<TIPO>::elemento(posicion<TIPO> posic){}      template <class TIPO>    TIPO&           conjunto<TIPO>::elemento(int posic){TIPO var;                                                                            return var;}       template <class TIPO>   const TIPO&     conjunto<TIPO>::elemento(posicion<TIPO> posic) const{}   template <class TIPO> int conjunto<TIPO>::getCardinalidad(){return 0;}   template <class TIPO> void conjunto<TIPO>::resize(int tam){};  
Espero que te funciones

etchner:
Muchas gracias, creía que solo era necesario indicar la plantilla al principio de la clase.  ya le voy pillando el truco al uso de las templates ;)

Navegación

[0] Índice de Mensajes

Ir a la versión completa