tipos sirven resueltos que plantillas para objetos metodos los funciones ejercicios ejemplos codigo clases c++ templates undefined-reference

sirven - Referencia indefinida de C++ al método de clase de plantilla



para que sirven los templates c++ (2)

Siempre consigo

referencia indefinida a `Graph :: InsertVertex (std :: string) ''

si compilo mi proyecto! ¿Alguna pista de por qué no puede resolver esta referencia? (todos los archivos están en la carpeta del proyecto netbeans)

// main.cpp

#include <cstdlib> #include <string> #include "Graph.h" using namespace std; int main(int argc, char** argv) { Graph<string> *graph = new Graph<string>(); // <--- ERROR graph->InsertVertex("A"); return 0; }

// Node.h

#include <iostream> #include "Graph.h" template<class T> class Node { friend class Graph; public: Node(T val) { this->data = val; this->vertList = NULL; this->next = NULL; } Node(const Node& orig); virtual ~Node(); private: T data; Node<T> *vertList; Node<T> *next; int status; };

// Graph.h

#include <iostream> #include "Node.h" template <class T> class Graph { public: Graph() { head = NULL; } void InsertVertex(T val); void InsertEdge(T v_val, T e_val); void PrintVertices(); void PrintEdges(T v_val); void DeleteEdge(T v_val, T e_val); void DeleteVertex(T val); void bfs(); private: Node<T> *head; };

// Graph.cpp

#include "Graph.h" template <class T> void Graph<T>::InsertVertex(T val) { Node<T> *temp = new Node<T>(val); if(head == NULL) head = temp; else { Node<T> node = head; while(node->vertList != NULL) node = node->vertList; node->vertList = temp; } } template <class T> void Graph<T>::InsertEdge(T v_val, T e_val) { if (head != NULL) { Node<T> *k = head; Node<T> *t = head; Node<T> *temp = new Node<T> (e_val); while (t != NULL) { if (t->data == v_val) { Node<T> *s = t; while (s->next != NULL) s = s->next; s->next = temp; while (k != NULL) { if(k->data == e_val) break; k = k->vertList; } temp->vertList = k; return; } t = t->vertList; } // end while loop } else std::cout << "Add first vertices to the graph" << std::endl; } template <class T> void Graph<T>::PrintEdges(T v_val) { Node<T>* t = head; while (t != NULL) { if (t->data == v_val) { while (t->next != NULL) { std::cout << t->next->vertList->data << " "; t = t->next; } } t = t->vertList; } } template <class T> void Graph<T>::PrintVertices() { Node<T>* t = head; while (t != NULL) { std::cout << t->data << " "; t = t->vertList; } }


Debe definir funciones de miembro en un archivo de encabezado, porque al crear una instancia de una plantilla, el compilador necesita tener acceso a la implementación de los métodos, para crear una instancia con el argumento de la plantilla.

En tu ejemplo:

template <class T> class Graph { public: void InsertVertex(T val) { Node<T> *temp = new Node<T>(val); if(head == NULL) head = temp; // ... } // ... private: Node<T> *head; };


Normalmente desea que los métodos de su plantilla en el encabezado, por lo que se compilan cuando sea necesario. En caso de que realmente desee ocultarlo en el archivo de implementación, tiene que crear una instancia explícita de la plantilla en Graph.cpp como

template class Graph<string>;

Ya que tienes que hacer eso para cada tipo T que pretendas usar con Graph<T> , el punto de la clase de la plantilla es algo derrotado y es mejor que pongas todo en el encabezado