Template Compilation Errors
Mar 9, 2012 at 2:03am UTC
Hi, can someone help me figure out what I am suppose to do with these errors.
PriorityQueue.h:15: error: template declaration of ‘hNode<T> hNode’
PriorityQueue.h:22: error: template declaration of ‘vNode<T> vNode’
Here is my code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
#ifndef _PRIORITYQUEUE_H_
#define _PRIORITYQUEUE_H_
#include <map>
#include <string>
#include <vector>
using namespace std;
template <class T>
struct hNode
{
float priority;
int * v_index;
}
hNode;
template <class T>
struct vNode
{
T obj;
int h_index;
}
vNode;
template <class T>
class PriorityQueue
{
public :
PriorityQueue();
~PriorityQueue();
void insert(T obj,float priority);
T front();
T pop();
bool isEmpty();
void changePriority(T obj, float new_priorty);
void remove(T obj);
int PercolateUp(int index);
int PercolateDown(int heapIndex);
int getChild(int index);
private :
int size;
int heapSize;
int valueSize;
map<T, int *> vMap;
vector<hNode<T> > heapVector;
vector<vNode<T> > valueVector;
};
#endif
Thank you for your time.
Mar 9, 2012 at 2:19am UTC
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
template <class T>
struct hNode
{
float priority;
int * v_index;
}; // *** add a ; here
// hNode; // *** and remove this
template <class T>
struct vNode
{
T obj;
int h_index;
}; // ***
// vNode; // ***
// ...
Mar 9, 2012 at 2:27am UTC
Thank you! That fixed the errors, but not I am getting a mass of undefined references for my main:
main.cpp:(.text+0x7c): undefined reference to `PriorityQueue<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >::PriorityQueue()'
main.cpp:(.text+0xbf): undefined reference to `PriorityQueue<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >::insert(std::basic_string<char, std::char_traits<char>, std::allocator<char> >, float)'
and the list goes on for all the calls. I will provide my main function as well:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
#include "PriorityQueue.h"
#include <iostream>
#include <string>
using namespace std;
int main()
{
PriorityQueue <string> queue;
queue.insert ( "str 3" , 3);
queue.insert ("str 2" ,4);
queue.insert ( "str 0" ,1);
queue.insert ( "str 7" ,2);
queue.insert ( "str 5" ,5);
queue.front();
queue.pop();
queue.changePriority("str 2" , 1);
queue.remove("str 7" );
return 0;
}
Mar 9, 2012 at 2:44am UTC
Mar 9, 2012 at 2:57am UTC
Put the definitions of the member functions in PriorityQueue.h, which you include in main.
I'm a little confused to what you are saying to do here
Mar 9, 2012 at 3:05am UTC
Your header should look like this:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
#ifndef _PRIORITYQUEUE_H_
#define _PRIORITYQUEUE_H_
#include <map>
// ...
template <class T>
class PriorityQueue
{
public :
PriorityQueue();
// ...
void insert(T obj,float priority);
// ... other member functions
private :
int size;
// ... other members
};
template < class T > PriorityQueue<T>::PriorityQueue() // definition of default constructor
{
// TODO : ...
}
template < class T > void PriorityQueue<T>::insert( T obj, float priority ) // definition of insert
{
// TODO : ...
}
// define other member functions
#endif // #ifndef _PRIORITYQUEUE_H_
Last edited on Mar 9, 2012 at 3:07am UTC
Mar 9, 2012 at 3:15am UTC
Do I still need to do that if they are defined in my cpp file?
Here is all of my code:
Header File:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
#ifndef _PRIORITYQUEUE_H_
#define _PRIORITYQUEUE_H_
#include <map>
#include <string>
#include <vector>
#include <iostream>
using namespace std;
template <class T>
struct hNode//heap node struct keeps track of the priority and the value index
{
float priority;
int * v_index;
};
//hNode;
template <class T>
struct vNode //value node struct, keeps track of the obj and the heap index
{
T obj;
int h_index;
};
//vNode;
template <class T>//template class
class PriorityQueue
{
public :
PriorityQueue();//constructor
~PriorityQueue();//desctructor
void insert(T obj,float priority);
T front();
T pop();
bool isEmpty();
void changePriority(T obj, float new_priorty);
void remove(T obj);
int PercolateUp(int index);
int PercolateDown(int heapIndex);
int getChild(int index);
private :
int size;
int heapSize;
int valueSize;
map<T, int *> vMap;//map data structure
vector<hNode<T> > heapVector;//heap vector
vector<vNode<T> > valueVector;//value vector
};
#endif
CPP File:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159
#include "PriorityQueue.h"
#include <iostream>
using namespace std;
template <class T>
PriorityQueue<T>::PriorityQueue()//constructor
{
int size=0;
int heapSize = 0;
int valueSize = 0;
}
template <class T>
PriorityQueue<T>::~PriorityQueue()//destructor
{
cout << "deleted" << endl;
}
template <class T>
void PriorityQueue<T>::insert(T obj, float priority)//inserts an object with a given priority
{
if (size = 0)//if size = 0
{hNode<T> heapNode;//declare heap node
heapNode.v_index[0] = 0;//value index = 0
heapNode.priority = priority;//priority = heap priority
heapSize ++;
vNode<T> valueNode;
valueNode.h_index = 1;
valueNode.obj = obj;//object = value object
valueSize++;
heapVector[1] = heapNode;
valueVector[0] = valueNode;
vMap.insert(obj,heapNode.v_index);
}
if (size >= 1)//if size is 1 or more
{ vNode<T> valueNode;
valueNode.obj = obj;//object = object
int i = 0;
while ( i < valueSize && obj.compare( valueVector[i].obj) < 0)
{i++;
}
for (int j = valueSize; j > i; j--)
{valueVector[j] = valueVector[j-1];
heapVector[valueVector[j].h_index].v_index[0] = j;
}
valueVector[i] = valueNode;
valueSize++;
hNode<T> heapNode;
heapNode.priority = priority;
heapNode.v_index = i;
heapVector[heapSize + 1] = heapNode;
PercolateUp(heapSize + 1);
heapSize++;
vMap.insert(obj,heapNode.v_index);
}
}
template <class T>
T PriorityQueue<T>::front()//returns the object with the highest priority
{
return valueVector[heapVector[1].v_index[0]];//gets the front node
}
template <class T>
T PriorityQueue<T>::pop()//removes and returns object with the highest priority
{
T *tempObj;
tempObj = front();//to return object
heapVector[1] = heapVector[heapSize];
heapSize--;//removes
PercolateDown(1);//reorder
return *tempObj;
}
template <class T>
bool PriorityQueue<T>::isEmpty()//checks to see if the heap is empty
{
if (heapSize == 0)
{
return true ;
}
else false ;
}
template <class T>
void PriorityQueue<T>::changePriority(T obj, float new_priority)//changes the priority of an object to a new priority
{
heapVector[valueVector[*vMap[obj].h_index].priority] = new_priority;
int down_index = PercolateUp(*vMap[obj].h_index);
PercolateDown(down_index);
}
template <class T>
void PriorityQueue<T>::remove(T obj)//removes an object from the priority queue
{
float newPriority;
newPriority = heapVector[1].priority - 1;
changePriority(obj,newPriority);
pop();
}
template <class T>
int PriorityQueue<T>::PercolateDown(int heapIndex)//reorders the heap going down
{
bool perc = true ;
int i = heapIndex;
while (perc && (2*i) < heapSize + 1)
{
perc = false ;
if ((2*i) == heapSize && (heapVector[i].priority < heapVector[2*i].priority))
{hNode<T> temp = heapVector[i];
heapVector[i] = heapVector[2*i];
heapVector[2*i] = temp;
valueVector[heapVector[i].v_index].h_index = i;
valueVector[heapVector[i*2].v_index].h_index = i*2;
i = i*2;
}else if ((2*i) != heapSize && heapVector[i].priority < heapVector[getChild(i)].priority)
{int index = getChild(i);
hNode<T> temp = heapVector[i];
heapVector[i] = heapVector[index];
heapVector[index] = temp;
valueVector[heapVector[i].v_index].h_index = i;
valueVector[heapVector[index].v_index].h_index = index;
perc = true ;
i = index;
}
}
return i;
}
template <class T>
int PriorityQueue<T>::getChild(int index)//chooses the child to percolate
{
if (heapVector[2*index].priority < heapVector[2*index + 1].priority)
return 2*index+1;
return 2*index;
}
template <class T>
int PriorityQueue<T>:: PercolateUp(int index)//reorders the heap going up
{
bool perc = true ;
int i = index;
while (perc && i<0)
{
perc = false ;
if (heapVector[i].priority < heapVector[i/2].priority)
{
perc = true ;
hNode<T> temp = heapVector[i];
heapVector[i] = heapVector[i/2];
heapVector[i/2] = temp;
valueVector[heapVector[i].v_index].h_index = i;
valueVector[heapVector[i/2].v_index].h_index = i/2;
}
i = i/2;
}
return i;
}
Main:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
include "PriorityQueue.h"
#include <map>
#include <string>
#include <vector>
#include <iostream>
using namespace std;
int main()
{
PriorityQueue <string> queue;
queue.insert ( "str 3" , 3);
queue.insert ("str 2" ,4);
queue.insert ( "str 0" ,1);
queue.insert ( "str 7" ,2);
queue.insert ( "str 5" ,5);
queue.front();
queue.pop();
queue.changePriority("str 3" , 1);
queue.remove("str 5" );
return 0;
}
Thanks Again for your help!
Mar 9, 2012 at 3:26am UTC
Move everything in the cpp file to the header file. And throw the cpp file away.
Or rename PriorityQueue.cpp as PriorityQueue.implementation.h and then
#include "PriorityQueue.implementation.h"
towards the end of PriorityQueue.h
Read this first, before you do anything else:
http://www.parashift.com/c++-faq-lite/templates.html#faq-35.12
Last edited on Mar 9, 2012 at 3:32am UTC
Topic archived. No new replies allowed.