Templating

Hi guys. I'm having problem with template. Please enlighten me. The files are listed below.

BinaryTree.h
#ifndef BINARYTREE_H
#define BINARYTREE_H

#include <iostream>
#include <algorithm>

using namespace std;

template<class T> struct Node
{
T info;
Node<T> *lLink;
Node<T> *rLink;
};

template<class T> class BinaryTree
{
public:
BinaryTree();
~BinaryTree();
.
.
.


BinaryTree.cpp
#include <iostream>
#include "BinaryTree.h"

using namespace std;

template<class T> BinaryTree<T>::BinaryTree() { root = NULL; }
.
.
.


BinarySearchTree.h
#ifndef BINARYSEARCHTREE_H
#define BINARYSEARCHTREE_H

#include <iostream>
#include "Map.h"
#include "BinaryTree.h"

using namespace std;

template<class T> class BinarySearchTree: public BinaryTree<T>
{
public:
BinarySearchTree();
~BinarySearchTree();

private:
};
#endif


BinarySearchTree.cpp
#include <iostream>
#include "BinarySearchTree.h"

using namespace std;

template<class T> BinarySearchTree<T>::BinarySearchTree(): BinaryTree() { }

template<class T> BinarySearchTree<T>::~BinarySearchTree() { }


Main.cpp
#include <iostream>
#include "BinarySearchTree.h"

using namespace std;

int main()
{
BinarySearchTree<Map> test;

system("pause");
return 0;
}

I will get an error:
Main.obj : error LNK2019: unresolved external symbol "public: __thiscall BinaryTree<class Map>::BinaryTree<class Map>(void)" (??0?$BinaryTree@VMap@@@@QAE@XZ) referenced in function "public: __thiscall BinarySearchTree<class Map>::BinarySearchTree<class Map>(void)" (??0?$BinarySearchTree@VMap@@@@QAE@XZ)
Main.obj : error LNK2019: unresolved external symbol "public: __thiscall BinaryTree<class Map>::~BinaryTree<class Map>(void)" (??1?$BinaryTree@VMap@@@@QAE@XZ) referenced in function "public: __thiscall BinarySearchTree<class Map>::~BinarySearchTree<class Map>(void)" (??1?$BinarySearchTree@VMap@@@@QAE@XZ)
C:\Users\Faizal Rahman\documents\visual studio 2010\Projects\Assg2v2\Debug\Assg2v2.exe : fatal error LNK1120: 2 unresolved externals

What is happening? :(
Move your BinarySearchTree.cpp code into BinarySearchTree.h. Same with BinaryTree.

When the compiler is compiling BinarySearchTree.cpp, it has no idea that there exist a Main.cpp somewhere that needs a BinarySearchTree<Map>. So it does not compile BinarySearchTree<Map>::BinarySearchTree() or BinarySearchTree<Map>::~BinarySearchTree().

And then linking fails because Main.cpp is trying to call those functions. In general, template code goes into header files.
Last edited on
if you would like i could provide you with the header to a balanced binary search tree (leaf depth is at the most 1 apart), its a well made library/class and can sort class types or anything
even if its something you would like to do urself you could use it as a guide...
if you want it email me: elliotmendiola@gmail.com
Thank you all for the prompt replies! I would have move all .cpp into .h but is unable to do so as i am working on a school assignment and they emphasized that i follow a header and source structure. In response to StewBond's reply, I'm working in a Visual Studio 2010 environment. I can't seem to find an .inl extension. Is there any other ways around this.
closed account (zb0S216C)
.INL files are nothing special. make sure the file resides within the same folder as you header. Within the header, #include it at the bottom of the header -- below the class/function.

Wazzak
Last edited on
If you want to keep your template definitions in your .cpp file then you will need to explicitly tell the compiler what types to instantiate. Inside your .cpp file you will need to add this...

BinaryTree.cpp
1
2
//After all definitions for this class...
template class BinaryTree<Map>;


You will need to do this for your other template classes as well in their respective .cpp files and do this for all types you plan on using... in other words you could have...

1
2
3
4
5
template class BinaryTree<Map>;
template class BinaryTree<int>;
template class BinaryTree<string>;
template class BinaryTree<ComplexData>;
//... etc etc 


Framework's method also does the same logically, in that you will still be using your .cpp files, the difference is that you are actually pulling in line by line the definitions for the member functions into your header. The instantiation is taking place in main (Where alternative template instantiation is taking place in the .cpp file for that class when you explicitly do this). Both easily fix your problem, so choose your preferred method.
Last edited on
Topic archived. No new replies allowed.