-1
1>------ Build started: Project: project4, Configuration: Debug Win32 ------
1>  proj4_driver.cpp
1>proj4_driver.obj : error LNK2019: unresolved external symbol "public: class cop4530::BST<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > > const & __thiscall cop4530::BST<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > >::operator=(class cop4530::BST<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > > const &)" (??4?$BST@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@cop4530@@QAEABV01@ABV01@@Z) referenced in function _main
1>proj4_driver.obj : error LNK2019: unresolved external symbol "public: __thiscall cop4530::BST<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > >::BST<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > >(int)" (??0?$BST@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@cop4530@@QAE@H@Z) referenced in function _main
1>proj4_driver.obj : error LNK2019: unresolved external symbol "public: __thiscall cop4530::BST<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > >::BST<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > >(class cop4530::BST<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > > const &)" (??0?$BST@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@cop4530@@QAE@ABV01@@Z) referenced in function _main
1>proj4_driver.obj : error LNK2019: unresolved external symbol "public: __thiscall cop4530::BST<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > >::BST<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > >(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >,int)" (??0?$BST@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@cop4530@@QAE@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@H@Z) referenced in function _main
1>proj4_driver.obj : error LNK2019: unresolved external symbol "public: class cop4530::BST<int> const & __thiscall cop4530::BST<int>::operator=(class cop4530::BST<int> const &)" (??4?$BST@H@cop4530@@QAEABV01@ABV01@@Z) referenced in function _main
1>proj4_driver.obj : error LNK2019: unresolved external symbol "public: __thiscall cop4530::BST<int>::BST<int>(int)" (??0?$BST@H@cop4530@@QAE@H@Z) referenced in function _main
1>proj4_driver.obj : error LNK2019: unresolved external symbol "public: __thiscall cop4530::BST<int>::BST<int>(class cop4530::BST<int> const &)" (??0?$BST@H@cop4530@@QAE@ABV01@@Z) referenced in function _main
1>proj4_driver.obj : error LNK2019: unresolved external symbol "public: __thiscall cop4530::BST<int>::BST<int>(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >,int)" (??0?$BST@H@cop4530@@QAE@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@H@Z) referenced in function _main
1>c:\users\ah09e\documents\visual studio 2010\Projects\project4\Debug\project4.exe : fatal error LNK1120: 8 unresolved externals
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

This here is a driver:

    #include <iostream>
    #include <string>
    #include "bst.h"

    using namespace std;
    using namespace cop4530;

    int main() {
    string input;

// get a list of integer values
cout << "Enter a list of integer values in one line: ";
getline(cin, input);

// create a binary search tree
BST<int> bst1(input);
if (!bst1.empty()) {
    cout << "Inorder traversal: ";
    bst1.printInOrder();
    cout << "Level order traversal: ";
/////////////bst1.printLevelOrder();

    // test copy constructor
    BST<int> bst2(bst1);
    cout << "Testing copy constructor: ";
    //////////////bst2.printLevelOrder();

    // test assignment operator
    BST<int> bst3;
    bst3 = bst1;
    cout << "Testing assignment operator: ";
    ////////////bst3.printLevelOrder();
 }

// get a list of string values
cout << "Enter a list of string values in one line: ";
getline(cin, input);

// create a binary search tree
BST<string> bsts1(input);
if (!bsts1.empty()) {
    cout << "Inorder traversal: ";
    bsts1.printInOrder();
    cout << "Level order traversal: ";
////////bsts1.printLevelOrder();

    // test copy constructor
    BST<string> bst2(bsts1);
    cout << "Testing copy constructor: ";
    ////////////bst2.printLevelOrder();

    // test assignment operator
    BST<string> bst3;
    bst3 = bsts1;
    cout << "Testing assignment operator: ";
    ///////////bst3.printLevelOrder();
 }

cout << "Enter a list of integer values: ";
getline(cin, input);
/////bst1.buildFromInputString(input);
cout << "Level order traversal: ";
////bst1.printLevelOrder();

cout << "\n===================\n";
cout << "Operation Manual:" << endl;
cout << "d: delete value;\ti: insert value;" << endl;
cout << "h: height of tree; \tn: number of nodes" << endl;
cout << "o: in order print; \tl: level order print" << endl;
cout << "s: search value;\tq: quit" << endl;
cout << "===================\n";
cout << "choice: ";
int tmp;
while (getline(cin, input)) {
if (input == "q")
    break;
if (input == "d") {
    cout << "Type value to delete: ";
    cin >> tmp;
    cin.ignore();
    bst1.remove(tmp);
} else if (input == "i") {
    cout << "Type value to insert: ";
    cin >> tmp;
    cin.ignore();
    bst1.insert(tmp);
} else if (input == "o") {
    cout << "In order traversal: ";
    bst1.printInOrder();
} else if (input == "l") {
    cout << "Level order traversal: ";
    ///////bst1.printLevelOrder();
} else if (input == "h") {
    cout << "Height: ";
    cout << bst1.height() << endl;
} else if (input == "n") {
    cout << "Number of nodes: ";
    cout << bst1.numOfNodes() << endl;
} else if (input == "s") {
    cout << "Type value to search: ";
    cin >> tmp;
    cin.ignore();
    if (bst1.contains(tmp)) {
    cout << "contains " << tmp << endl;
    } else {
    cout << "does not contains " << tmp << endl;
    }
}

cout << "\n===================\n";
cout << "Operation Manual:" << endl;
cout << "d: delete value;\ti: insert value;" << endl;
cout << "h: height of tree; \tn: number of nodes" << endl;
cout << "o: in order print; \tl: level order print" << endl;
cout << "s: search value;\tq: quit" << endl;
cout << "===================\n";
cout << "choice: ";
}
return 0;
}

And bst.h:

#ifndef COP4530_PROJ4_H
#define COP4530_PROJ4_H

#include<iostream>
#include<string>
using std::string;

namespace cop4530{

//using std::string;
int default_threshold_value = 1;

template <typename T>
class BST
{

public:

BST(int th=default_threshold_value); 
BST(const string input, int th=default_threshold_value);
BST(const BST&);
~BST();//
void buildFromInputString(const string input);
const BST & operator=(const BST & rhs);//
bool empty();//


void printInOrder() const;//
//void printLevelOrder() const;//
int numOfNodes() const;//
int height() const;//
void makeEmpty();//
void insert(const T& v);//
void remove(const T& v);//
bool contains (const T& v);//


private:
struct BSTNode
{
T element;
BSTNode *left;
BSTNode *right;
int height;
//void printInOrder(BSTNode *t) const;

BSTNode(const T & theElement, BSTNode *lt, BSTNode *rt, int h=0)
    : element(theElement), left(lt), right(rt), height(h) {}
};

BSTNode *root;

void printInOrder(BSTNode *t) const;//
//void printLevelOrder(BSTNode *t) const;
void makeEmpty(BSTNode* &t);//
void insert(const T& v, BSTNode *&t);//
void remove(const T& v, BSTNode *&t);//
bool contains(const T& v, BSTNode *&t);//
int numOfNodes(BSTNode *t) const;//
int height(BSTNode *t) const;//
BSTNode * clone(BSTNode *t) const;//

};
#include "bst1.hpp"
}
#endif

And here is the bst1.hpp

template <typename T>
void BST<T>::buildFromInputString(const string input)
{
    //////////makeEmpty();
    cin >> input;

}

template <typename T>
BST<T>::~BST()
{
    makeEmpty();
}

/*template <typename T>
const BST<T>::BST & operator=(const BST & rhs)
{
    if (this != &rhs)
    {
        makeEmpty();
        root = clone( rhs.root)
    }
    return *this;
}*/

template <typename T>
bool BST<T>::empty()
{
//if (contains(root)==(-1)) 
if ( 1==1)  
    return true;
else
    return false;
}

template <typename T>
void BST<T>::printInOrder() const
{
    printInOrder(root);
}

/*template <typename T>
void BST<T>::printLevelOrder() const
{
    printLevelOrder(root);
}*/

template <typename T>
int BST<T>::numOfNodes() const
{
    return numOfNodes(root);
}
template <typename T>
int BST<T>::height() const
{
    return height(root);
}

template <typename T>
void BST<T>::makeEmpty()
{
    makeEmpty(root);
}

template <typename T>
void BST<T>::insert(const T& v)
{
    insert(v, root);
}

template <typename T>
void BST<T>::remove(const T& v)
{
    remove(v, root);
}

template <typename T>
bool BST<T>::contains(const T& v)
{
    return contains(v, root);
}

template <typename T>
bool BST<T>::contains(const T& v, BSTNode *&t)
{
    if( t == NULL)
        return false;
    else if(v < t->element)
        return contains(v, t->left);
    else if(t->element < v)
        return contains(v, t->right);
    else
        return true;
}

template <typename T>
int BST<T>::numOfNodes(BSTNode *t) const
{
    int nodes = 0;
    if (t!=NULL)
    {
        nodes++;
        numOfNodes(t->left);
        numOfNodes(t->right);
    }
    return nodes;
}

template <typename T>
void BST<T>::printInOrder(BSTNode *t) const
{

if (left != 0)
printInOrder(t->left);
cout << t << endl;
if (right != 0)
printInOrder(t->right);

}


//void BST<T>::printLevelOrder(BSTNode *t) const


template <typename T>
void BST<T>::makeEmpty(BSTNode * & t)
{
    if(t != NULL)
    {
        makeEmpty(t->left);
        makeEmpty(t->right);
        delete t;
    }
    t = NULL;
}

template <typename T>
void BST<T>::insert(const T& v, BSTNode *&t)
{
    if(t = NULL)
        t = new BSTNode(v, NULL, NULL);
    else if(v < t->element)
        insert(v,t->left);
    else if(t->element < v)
        insert(v,t->right);
    else
        ;
}

template <typename T>
void BST<T>::remove(const T& v, BSTNode *&t)
{
    if(t == NULL)
        return;
    if(v < t->element)
        remove(v, t->left);
    else if (t->element < v)
        remove(v,t->right);
    else
    {
        BSTNode *oldNode = t;
        t = (t->left != NULL) ? t->left : t->right;
        delete oldNode;
    }

}
//else if (t->left != NULL && t->right != NULL)



template <typename T>
int BST<T>::height(BSTNode *t) const
{
    return t == NULL ? -1: t->height;
}

template <class T>
typename BST<T>::BSTNode * BST<T>::clone(BSTNode *t) const
{
    if(t==NULL)
        return NULL;

    return new BSTNode( t->element, clone(t->left), clone(t->right));

}

I'm having a linker Problem. Couldn't find any code on the site that would address my problem specifically. Been working on a binary search tree but with little results remedying this particular aspect. As far as I'm concerned all libraries and files are added in their respective areas, will deeply appreciate some help.

DarkKunai99
  • 105
  • 1
  • 4
  • 13

3 Answers3

0

You must not separate interface and implementation for templates. Define your methods in you .h-file, otherwise the compiler can't create your concrete types.

bash.d
  • 13,029
  • 3
  • 29
  • 42
  • Note that you can separate interface and implementation into source and header files if you use [explicit instantiation](http://stackoverflow.com/a/1724632/1227469). – JBentley Apr 05 '13 at 20:13
  • I have done this before multiple times, not to mention that it is an in class requirement that the interface and implementation be separated into two different files. Rest assured, both are header files. – DarkKunai99 Apr 05 '13 at 20:16
  • Only if the compiler supports this... – bash.d Apr 05 '13 at 20:21
0

If you really want to separate the template implementation and delcaration. You should change the end of line inside bst.h from

#include "bst1.hpp"

to

#include "bst1.cpp"

and bst1.hpp should be renamed to bst1.cpp ( your bst1.hpp really contains all implementations you need), therefore, the compiler can instantiate your templates by knowing the definitions inside bst1.cpp.

taocp
  • 23,276
  • 10
  • 49
  • 62
0
getline(cin, input);

doesn't make any sense in a driver, similary cout, doesn't also make any sense in a driver.

For driver programing you need to start small and advance step by step.

Starting small begins with debugging (and reading the debugging messages with an program) of the stuff.

You can find here a tutorial for getting started.

For more i suggest you check out the driver sdk from Microsoft, this helps greatly.

Quonux
  • 2,975
  • 1
  • 24
  • 32