Using Templates to define classes in C++

Hi,

I am a beginner in C++ and to get my hands dirty I was trying to implement a heap data structure. I have defined two header files, myheapnode.h and myheap.h which contain the definition of two classes, "heap" and "heapnode". Those two files are shown below.

myheapnode.h :-

#ifndef MYHEAPNODE_H
#define MYHEAPNODE_H

template< class T > class heap;

template< class T >
class heapnode
{
friend class heap<T>;
public :
heapnode(T,int);
heapnode(T,heapnode<T> *,int);
T getdata() { return data; };
private :
T data;
int mynum;
heapnode<T> *parent;
heapnode<T> *lchild;
heapnode<T> *rchild;
};

#endif

myheap.h :-

#ifndef MYHEAP_H
#define MYHEAP_H

#include "myheapnode.h"

template< class T >
class heap
{
public :
heap(T);
~heap();
< Some other deifintions >
private :
heapnode<T> *rootptr;
heapnode<T> *endptr;
< Some other definitions >
};

#endif

I have a seperate file containing the functions defined in the "myheap" and "myheapnode" classes, including the respective constructors and destructors.
In my code,"trial.cpp" when I try to initialize a heap as follows:-

heap<int> heaptrial(10);

I get an error saying:-
trial.cpp:(.text+0x7e): undefined reference to `heap<int>::heap(int)'
trial.cpp:(.text+0x18d): undefined reference to `heap<int>::~heap()'

My code ran perfectly well before I modified it to use templates. I would really appreciate it if someone could help me out with this.

Thanks in advance.
Mahesh
You must put the code for template classes/functions in their header files. You can't really put the code in .cpp files.

Hi,
Thanks a lot jsmith. It worked when I put everything in the same file. I am wondering though, when I wasnt using templates, it worked just fine with the function calls in a different file. Why is it that templates need everything to be in the same file.
Hi,
Thanks a lot jsmith. It worked when I put everything in the same file. I am wondering though, when I wasnt using templates, it worked just fine with the function calls in a different file. Why is it that templates need everything to be in the same file.
closed account (NqG36Up4)
You could find this helpful, I did:
http://www.cplusplus.com/doc/tutorial/templates/
Think about it this way.

Say you have

1
2
3
4
5
6
7
8
9
10
template< typename T >
class Adder {
  // Just an example
  public:
    Adder( T v );
    Adder operator+( const Adder& rhs ) const;
  private:
    T value;
};
T> Adder<T>::operator+( const Adder


in a header file, and then you put all the code in a .cpp file.
Suppose that all operator+ does is

 
return Adder( value + rhs.value );


Now when the compiler compiles the .cpp file, what is T? T could be almost any type -- int, short, char, float, double, even std::string. T could be more than one type: perhaps in your program somewhere you use Adder<int> whereas in another place you use Adder<float> and in a third place you use Adder<std::string>.

How's the compiler to know when compiling Adder.cpp? Short answer: it can't. Longer answer: it can, provided that in Adder.cpp you instantiate Adder with every different type your program will attempt to instantiate Adder with, but in practice most programmers don't do that for reasons of maintainability.

It matters because when the compiler is compiling the body of operator+, if T is of an integral type, it can generate an integer ADD instruction, but if T is of floating point type, then it must generate a floating point ADD instruction, and if T is std::string, it has to call std::string::operator+( const std::string& ) const instead. (etc, etc.)

Basically, the only point at which the compiler knows what T is, is when you instantiate it, for example in main.cpp or some other .cpp file. Only at that point can the compiler actually generate the assembler/machine code for the functions in Adder. But in order to do that, the compiler must be able to "see" the complete implementation of the class. The only way for the compiler to see the implementation is to #include it. Since it is never recommended to #include .cpp files, that leaves you with putting the complete implementation in the header file.
Topic archived. No new replies allowed.