Edit 1: This question what closed as a duplicate. While the suggested duplicate What is an undefined reference/unresolved external symbol error and how do I fix it? addresses the possible causes of such "undefined symbol errors" in a general, and very comprehensive, manner it does not address the exact cause of the error in my sitution. While it may be possible to reason based on the information provided in the linked post in a way that hones in on my problem, it is beyond me to do so and I would require further assistance. For these reasons, I believe that it is inaccurate to treat this is a duplicate question.
Edit 2: Reading Kerndog73's comment about putting all template functions into header files the following accepted answer to the following question Why can templates only be implemented in the header file? answers my question.
I am implementing a graph based on adjaency sets and have run into the following compiler error:
Undefined symbols for architecture x86_64:
"Vertex<int, int>::addEdge(Edge<int>)", referenced from:
HashGraph<int, int>::addEdge(int, int) in hash-graph-test-99739e.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
and I cannot manage to figure out why Vertex<int, int>::addEdge(Edge<int>)
would be undefined.
Below is the code that I believe to be relevent for this error:
hash-graph.cpp
/**
* Adds a non-existent, directed, edge from a "tail vertex" to a
* "head vertex" by modifying the adjacency set of the "tail vertex".
* If the passed in edge already exists, the method instead returns
* false.
*
* @param tail the vertex at which the edge starts
* @param head the vertex at which the edge ends
* @return false if edge already exists, else true
*/
template <class K, class V>
bool HashGraph<K, V>::addEdge(K tail, K head)
{
Vertex<K, V> vTail = getVertex(tail);
Edge<K> edge(head);
return vTail.addEdge(edge);
}
template <class K, class V>
Vertex<K, V> HashGraph<K, V>::getVertex(K key)
{
auto searchResult = graph.find(key);
if (searchResult != graph.end())
return searchResult->second;
throw "Vertex not found.";
}
edge.hpp
template <class K>
class Edge
{
private:
static const int NO_COST = -1;
K head;
double cost;
public:
Edge(K head);
Edge(K head, double cost);
K getHead() const {return head;}
double getCost() const {return cost;}
bool operator==(const Edge<K> &other) const
{
return (head == other.head && cost == other.cost);
}
};
template <class K>
Edge<K>::Edge(K head)
{
this->head = head;
cost = NO_COST;
}
vertex.hpp
template <class K, class V>
class Vertex
{
private:
K key;
V value;
std::unordered_set<Edge<K>> adjacencySet;
public:
Vertex(K key, V value);
K getKey() const {return key;} // TODO: what does const do here exaclty>
V getValue() const {return value;}
bool addEdge(Edge<K> edge);
// TODO: what does const do here exactly
bool operator==(const Vertex<K, V> &anotherVertex) const
{
return key == anotherVertex.key;
}
};
vertex.cpp
template <class K, class V>
bool Vertex<K, V>::addEdge(Edge<K> edge)
{
if (adjacencySet.find(edge) != adjacencySet.end())
{
adjacencySet.insert(edge);
return true;
}
return false;
}
Note that a lot of code has been omitted that exists in the various files. Personally, I am a bit suspicious of the getVertex
method, but have not been able to find anything concrete yet.
Could someone help me understand why this error is being thrown?