prob making class template

I can't figure out how to make a class template out of a class that i have already defined. Could someone explain to me how templates are implemented? My class code is below and I just need to know how to make it a template class with templated functions. Thanks!!

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
class iVec
{
public:
	iVec();//constructor
    int at(int);
    int size();
    void resize(int);
    void push_back(int);
    void pop_back();
	void print();

private:
	Node *iNode;
	int maxSize;
};
iVec::iVec(){
	iNode=0;
}//end constructor

//at function returns the index of a value
//that the programmer passes to the funtion.
int iVec::at(int n){
	Node *current=m;
	for(int count = 0; count<size();count++){
		if(n==current->data)
			return count;
		else
			current=current->next;
	}
	return NULL;
}//end at()
//function size() returns the number of elements in the list.
int iVec::size(){
	Node *temp=m;
	int count = 0;
	while(temp!=NULL){
		temp=temp->next;
		count++;
	}
	return count;
}
//Function resize() resizes the container.
//If the new size is less than the current
//size, then the extra nodes are discarded.
//If it is larger, then empty nodes are
//added to the end of the container.
void iVec::resize(int n){
	cout<<"The container is being resized to "<<n<<" elements."<<endl<<endl;
	Node *temp;
	temp = m;
	//if n > size of the container
	//then make new empty nodes until
	//size==n
	if(n>size()){
		while(temp->next!=NULL&&size()<=n){
			temp=temp->next;
			if(temp->next==NULL)
				temp->next=new Node;
		}//end while
	}//end outside if
	//if n<size() then delete the values
	//past n.
	if(n<size()){
		while(temp->next!=NULL&&size()>n){
			temp=temp->next;
			if(temp->next==NULL){
				pop_back();
				temp=m;
			}//end inside if
		}//end while
	}//end if
}//end resize()

//Function push_back adds a node to
//the end of the container. If the 
//list is empty, then a new node is
//created with the value n.
void iVec::push_back(int n){
	Node *temp,*temp2;
	//if container is empty then
	//initiate the first node value.
	//with the user defined value.
	if( m == NULL )
    {
      m = new Node;
      m->data = n;
      m->next = NULL;
    }//end if
	//else add a node of the user
	//defined value to the end of 
	//the container
    else
    {
		temp = m;
		while( temp->next != NULL ){
			temp = temp->next;
		}//end while
		temp2 = new Node;
		temp2->data = n;
		temp2->next = NULL;
		temp->next = temp2;
	}//end else
	cout<<"The value "<<n<<" was added to the end of the container.";
	cout<<"\n";
}//end push_back()
//Function pop_back deletes the last value
//in the container. If no values exist in
//the list, a message is printed to the user
//and the function is exited.
void iVec::pop_back(){
	Node *current = m;
	Node *temp;
	//if the first node is empty then the program
	//notifies the user that the container is empty
	//and returns.
	if(current==NULL){
		cout<<"The container is empty.";
		return;
	}//end if
	//while deletes the last node in the list 
	while(current->next!=NULL){
		temp = current;
		current=current->next;
	}
	temp->next = NULL;
	delete current;
	cout<<"The last value in the container has been removed."<<endl<<endl;
	
}//end pop_back()
//Function print() prints all values
//in the container to the screen.
void iVec::print(){
	Node *temp;
 	cout<<endl<<"These are the container's elements:";
	for( temp = m ; temp != NULL ; temp = temp->next ){
		if(temp->data!=NULL)
			cout<<endl<<temp->data;
	}//end for
	cout<<endl<<endl;
}//end print() 
I recommend starting with a few small classes to get how it works.

For this I think you are going to have to template your Vec and your Node classes:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
template<typename T>
struct Node
{
    T data;
    Node<T>* next;
};

template<typename T>
class Vec
{
    Node<T>* node;
public:
    void push_back(const T& value);
    T& at(int);
};


Simply put T wherever the type you want to replace needs to be.
Pretty much agree with what Galik said.


On another matter, I think this function is logically incorrect if NULL has been defined to have the value 0 (zero):
1
2
3
4
5
6
7
8
9
10
11
12
//at function returns the index of a value
//that the programmer passes to the funtion.
int iVec::at(int n){
	Node *current=m;
	for(int count = 0; count<size();count++){
		if(n==current->data)
			return count;
		else
			current=current->next;
	}
	return NULL;
}//end at() 

Not to mention that it almost does the exact opposite of what vector<>::at() does, so will probably
be confusing/surprising to the user.
Ok I just don't get how the function templates are made with the implementations. I'm severely confused by templates I don't know where to start to ask questions cause the concept kinda makes since I just don't get all the syntax and passing T& values to the functions. Does that make a little sense?
Perhaps start with a simple example.

Suppose I had a Point class:

1
2
3
4
struct Point {
    Point( int x, int y ) : x( x ), y( y ) {}
    int x, y;
};


and now I want to make another Point class that uses doubles instead of ints. I could:

1
2
3
4
struct PointD {
    PointD( double x, double y ) : x( x ), y( y ) {}
    double x, y;
};


Notice that all I did was rename the class (struct) and replace all "int" with "double".

Or, I could use a template:

1
2
3
4
5
template< typename T >
struct Point {
    Point( T x, T y ) : x( x ), y( y ) {}
    T x, y;
};


Now Point<int> makes a struct named Point with x and y defined as int, and
Point<double> makes a struct named Point with x and y defined as double.

This is all templates really are.

If I want to move the implementation of the constructor outside the class
(struct), then I write it like:

1
2
3
4
5
6
7
8
template< typename T >
struct Point {
    Point( T x, T y );
    T x, y;
};

template< typename T >
Point<T>::Point( T x, T y ) : x( x ), y( y ) {}


So i'm getting an error on line 13 of the code below. can you not do what i did with *m in templates? To be honest, I didn't really understand what that actually did. I just know that I used *m whenever I wanted to access the first node in the list. But when i templated the class, I got error: syntax error : missing ';' before '*'

and also this error: missing type specifier - int assumed. Note: C++ does not support default-int

1
2
3
4
5
6
7
8
9
10
11
12
13
template<class T>
class Node
{
public: 
    T data;
    Node<T>* next;
	
	Node()
    {
    data=0;
    next=0;
    }//end Node()
}*m;//end class Node 
What is the *m for? It looks like you are declaring a global Node *. That's not a great thing to do anyway. You would probably be better making m a member of Vec.
Okay - what you are doing makes no sense. You have now made the Node a template. If you want to instantiate a node or a pointer to a node then you must write either:
1
2
3
// Where typename could be int, double, or whatever.
[code]Node<typename> theNodeObject;  
Node<typename>* theNodePointer;
[/code]

Did you read the template tutorial on this website? I'd also like to point out that it is not a very good idea to create something called iVec and then make it work like a linked list. vectors are not linked lists in C++. Those names have specific meanings to people who use the STL and what you have done will be very confusing to most users who know the STL.
Last edited on
If you really want to learn C++ and how templates work you'd be better off writing a program that uses the STL instead of trying to reinvent the wheel. Take a look at this.
http://cplusplus.com/forum/articles/10879/
Topic archived. No new replies allowed.