Sign in to follow this  

unresolved external symbol for a class using templates

This topic is 4553 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I'm trying to write a class for a binary heap using templates. The header file is pretty straightforward.
template <class T> class cBinaryHeap
{
private:
	int amount;		//amount of elements in array
	int	size;		//size of the array
	T*	array;		//the array
			
public:
	//constructor
	cBinaryHeap(int Size);

	//destructor
	~cBinaryHeap(void);

	//methods
	void	Add(T element);
	T	GetFirst(void);
	void	Print(void);
};
the definitions are in a separate file and look like this.
#include "cBinaryHeap.h"
	
//init
template <class T> cBinaryHeap<T>::cBinaryHeap(int Size)
{
  //stuff
}
	
//destructor
template <class T> cBinaryHeap<T>::~cBinaryHeap(void)
{
  //stuff
}

//add an element to the heap
template <class T> void cBinaryHeap<T>::Add(T element)
{
  //stuff
}
	
//get the first element from the heap
template <class T> T cBinaryHeap<T>::GetFirst(void)
{
  //stuff
}

//print the heap
template <class T> void cBinaryHeap<T>::Print(void)
{
  //stuff
}
in my main.cpp I just go
#include "cBinaryHeap.h"
#include <iostream>
using namespace std;

int main()
{
	cBinaryHeap<int> Heap(20);

	{for(int i = 0; i < 20; i++)
	{
		Heap.Add(rand()%40);
	}}

	Heap.Print();
	
	cin.get();
	return 0;
}
The problem is that the linker gives a couple unresolved external symbol errors.
error LNK2001: unresolved external symbol "public: __thiscall cBinaryHeap<int>::~cBinaryHeap<int>(void)" (??1?$cBinaryHeap@H@@QAE@XZ)
_main.obj : error LNK2001: unresolved external symbol "public: void __thiscall cBinaryHeap<int>::Print(void)" (?Print@?$cBinaryHeap@H@@QAEXXZ)
_main.obj : error LNK2001: unresolved external symbol "public: void __thiscall cBinaryHeap<int>::Add(int)" (?Add@?$cBinaryHeap@H@@QAEXH@Z)
_main.obj : error LNK2001: unresolved external symbol "public: __thiscall cBinaryHeap<int>::cBinaryHeap<int>(int)" (??0?$cBinaryHeap@H@@QAE@H@Z)
Usually when I get a linker error I just figure I forgot a library. So this is first for me :/

Share this post


Link to post
Share on other sites
Quote:
Original post by Shai
it works :)

I can't see the member functions under ClassView then though :/ (MSVC++ 6.0)


If you use MSVC 6.0, you should be happy that your templates work at all [grin]

Share this post


Link to post
Share on other sites
xMcBaiNx is *sortof* correct. According to The Standard (TM), it should be possible to seperate header and implementation for templates using the export keyword; unfortunately, aside from Comeau, few-to-no compilers actually support the keyword.

As an alternative, you can "hack" support for templates into source files:
header.cpp
#include "header.h"

... //implementation details here




main.cpp
#include ... //your normal includes, and then...
#include "header.cpp"

//now you need to provide a declaration using one of the types it will be
//specialized for -- e.g., if you use the class specialized with floats,
//place this somewhere at global scope
template <temp args> class Name<float> _nameFloat;




Contrived? Very. But it's the price we pay for non-compliance with The Standard.

NOTE: I'd love to guarantee the accuracy of this post, but at the moment I can't check on any of my personal files demonstrating this behavior -- my PSU decided to happily die on me recently.

EDIT: Before Fruny gets here, I'd like to say that I'm not entirely sure if it's necessary to declare this variable at global scope. I'd appreciate it if someone would test this type of declaration at local scope for me, because I can't put an IDE on this computer.

Share this post


Link to post
Share on other sites
A better way is using .inl (for "inline" - or some other extension; it doesn't really matter) files:


// foo.h
#ifndef FOO_H
#define FOO_H
// template declarations, and then at the end:
#include "foo.inl"
#endif

// foo.inl

// template implementations - the guy looking at the .h file doesn't have to see
// this part, at least

// foo.cpp
#include "foo.h"
// and proceed normally, without having to include a .cpp.

Share this post


Link to post
Share on other sites

This topic is 4553 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this