I was getting the following error from Visual Studio:
error LNK2019: unresolved external symbol "public: __thiscall BSTree::BSTreeNode::BSTreeNode(class TestData const &,class BSTree::BSTreeNode *,class BSTree::BSTreeNode *)" (??0BSTreeNode@?$BSTree@VTestData@@H@@QAE@ABVTestData@@PAV01@1@Z) referenced in function "protected: void __thiscall BSTree::insertHelper(class TestData const &,class BSTree::BSTreeNode * &)" (?insertHelper@?$BSTree@VTestData@@H@@IAEXABVTestData@@AAPAVBSTreeNode@1@@Z)
Here are the functions that the compiler brings into question:
template < typename DataType, class KeyType >
BSTree<DataType,KeyType>::BSTreeNode::BSTreeNode ( const DataType &nodeDataItem,
BSTreeNode *leftPtr, BSTreeNode *rightPtr ) {
left = leftPtr;
right = rightPtr;
dataItem = nodeDataItem;
}
template < typename DataType, class KeyType >
void BSTree<DataType,KeyType>::insertHelper (const DataType& d, BSTreeNode*& b) {
if (b == 0) {
b = new BSTreeNode(d, 0, 0);
}
else if (d.getKey() < b->dataItem.getKey()) {
insertHelper(d, b->left);
}
else if (d.getKey() > b->dataItem.getKey()) {
insertHelper(d, b->right);
}
else {
b->dataItem = d;
}
}
So I look them over and I believe my code looks correct. So I perform a rebuild and then there are no errors and the program fires up just fine. I asked my lab instructor about why this occurs, but he said that he did not have a suitable answer. This is something that I've seen more and more while my projects are becoming more complex.
I've done some research:
Difference between build, rebuild, and clean solution
Do I always need to Clean/Rebuild?
Is this something that just inevitably happens while working with the Visual Studio IDE? Is there anything that I can do to prevent this? Are there any consequences from having this issue come up (ie. is there a flaw in my code)?
UPDATED: It seems that this might be the cause for much of the linker errors that I've been witnessing the semester.
Here is the advice from a book:
"Compiling programs that use templated classes requires a change in what files are included using the #include preprocessor directive, and in how the program is compiled. Because of how C++ compilers process templated code, the program that creates objects of the classes (e.g., main.cpp) must include the class implementation file, not the class declaration file. That is, it must do
#include "Classname.cpp"
instead of the usual#include "Classname.h"
The rule is in effect the rest of this book. Because the main implementation file does a #include of the class implementation code, the class implementation code is not compiled separately."