views:

151

answers:

4

I am trying to implement a leftist tree using heaps as a base class. The following is the contents of heap.h:

template <class T>

class heap {
public:
    virtual void init(T*) = 0;
    virtual void insert(T*) = 0;
    virtual T delete_min() = 0;
};

The following is the contents of leftist.cpp:

#include "heap.h"

template <class T>
class leftist_tree : public heap<T> {
private:
    T* root;
public:
    void init(T* a) {}
    void insert(T* a) {}
    T delete_min() {T a; return a;}
};

I am passing another class leftist_node as a parameter to this class using the following definition:

leftist_tree<leftist_node> mytree;

I am getting an LNK 2001 unresolved external symbol error for functions init, insert and delete_min. What am I doing wrong?

Edit:

Okay the example I have given at this point is far too complex. I have tried to reproduce the same error on a smaller scale so that someone can identify the problem more easily. I have created the following sample files.

try.cpp

#include "stdafx.h"
#include "myclass.h"

int _tmain(int argc, _TCHAR* argv[])
{
    myclass<int> a;
    a.hello(3);
    return 0;
}

myclass.h

template <class T>

class myclass {
public:
    void hello(T);
};

myclass.cpp

#include "myclass.h"
#include <iostream>
using namespace std;

template <class T>
void myclass<T>::hello(T a){
    cout<<a<<endl;
    system("pause");
}

I get a similar error message:

1>try.obj : error LNK2001: unresolved external symbol "public: void __thiscall myclass::hello(int)" (?hello@?$myclass@H@@QAEXH@Z) 1>c:\users\meher anand\documents\visual studio 2010\Projects\try\Debug\try.exe : fatal error LNK1120: 1 unresolved externals

Can you tell me where I am going wrong right now? Thanks

+1  A: 

Whenever you see this error

error LNK20XX unresolved external symbol

It means that while linking the linker is unable to find the function definition. In your case it is error

Hope this helps you. Let me know if you need any more help

PK

Pavan
That's right up until the main function part. They either have a main or it's a library. The error specifically is listing the functions it can't find.
Lou Franco
Thanks a lot ive updated the post.
Pavan
+3  A: 

The template isn't instantiated for the type. The easiest way is to remove the .cpp from being compiled, and include it into the cpp where you use the template.

Another easy answer is to just define the whole template in the .h.

Lou Franco
+1  A: 

The following should work (tested with g++):

// File: heap.hh --------------------------
template <class T>
class heap {
public:a
    virtual void init(T*) = 0;
    virtual void insert(T*) = 0;
    virtual T delete_min() = 0;
};

// File: leftist_tree.hh ------------------
#include "heap.hh"
template <class T>
class leftist_tree : public heap<T> {
private:
    T* root;
public:
    void init(T* ) {}
    void insert(T* ) {}
    T delete_min() {T a; return a;}
};

// File: leftist_node.hh ------------------
struct leftist_node {
    int value;
};

// File: leftist_main.cpp -----------------
#include "leftist_tree.hh"
#include "leftist_node.hh"

int main() {
    leftist_tree< leftist_node > mytree;
}
ArunSaha
Might want to make `leftist_node` a `struct` so you can get to its member.
Mike DeSimone
@Mike DeSimone: Good suggestion, thanks for mentioning that. Edited to make that change.
ArunSaha
+3  A: 

Template functions are treated a little differently from regular functions. The compiler doesn't actually compile the function until you try to use it. If the only place you try to use it is a .cpp where the body of the function is undefined, it assumes it must be compiled somewhere else and makes a reference for the linker to fill in later.

In your case you defined the body of the functions in leftist.cpp, but you didn't use it there, you used it somewhere else. If you had defined it in the .h file then the definition would have been available everywhere you tried to use it and all would be well. If you had used the functions somewhere in leftist.cpp then the functions would have been created and the linker would have fixed everything up.

The general rule is to define the body of all template functions in the header files.

Mark Ransom
Thanks a lot for that. Learnt something new today. :)
Meher