I am trying to test my binary tree, but I am getting errors: The error occurs when I try to call a template function. For example: tree.insertNode(inp);. I get this error: request for member âinsertNodeâ in âtreeâ, which is of non-class type âmain()::binaryTree ()()â

I have defined my template and called the constructor in my program:

typedef BinaryTree<int> binaryTree;
  binaryTree tree();

I have linked my binaryTree.hpp, binaryTree.cpp and testPro.cpp in a make file and included #include "binaryTree.hpp" in testPro.cpp. testPro.cpp is where I am testing the tree and getting the errors.

Here is the binaryTree.hpp file:

#include <iostream>
using namespace std;
template <class T>
class BinaryTree
	struct TreeNode
		T value;
		TreeNode *left;
		TreeNode *right;
	int leafCount;
	TreeNode *root;
	void insert(TreeNode *&, TreeNode *&);
	void destroySubTree(TreeNode *);
	void deleteNode(T, TreeNode *&);
	void makeDeletion(TreeNode *&);
	void displayInOrder(TreeNode *);
	void displayPreOrder(TreeNode *);
	void displayPostOrder(TreeNode *);
	int countNodes(TreeNode *&);
    void countLeaves(TreeNode *);
	int getTreeHeight(TreeNode *);
	int numAtLevel(TreeNode *, int);
	BinaryTree()							// Constructor
		{ root = NULL; }
	~BinaryTree()							// Destructor
		{ destroySubTree(root); }
	void insertNode(T);
	// searchNode has been modified.
	T *searchNode(T);
	void remove(T);
	void displayInOrder()
		{	displayInOrder(root); }
	void displayPreOrder()
		{	displayPreOrder(root); }
	void displayPostOrder()
		{	displayPostOrder(root); }
	int numNodes();
	int numLeafNodes();
	int treeHeight();
	int getWidth();

Thank you in advance!

Read the error message. It says that in main, you are trying to call a member function on an object that is not of type class. I suspect the error should actually tell you that the object is not of type instance of class. In any case, that tells you that the (first) problem is

  • in main()
  • on a particular line

Since you didn't show us your code for main(), we can't really help. But you should not need help either: The error message should be sufficient for you to find (this) problem.

You should probably read this.

Basically, you can't really split template code in the traditional hpp/cpp files. This is because templates don't get compiled until they are used ("instantiated"). So all the code in the cpp file basically gets ignored by the compiler because it doesn't find, in that translation unit, an instantiation of the class template.

So, you basically have to put all the code in the header file (it doesn't have to be inside the class declaration, it just has to be in the header file). Also, a quick fix is to just #include the cpp file at the end of the header (within the include guards!). You will also have to declare all those functions with the "inline" keyword to avoid certain linkage errors if the same template is instantiated in different translation units.

Another option, which is often less convenient is to use explicit instantiation in the cpp file, as such:

template class BinaryTree<int>;

But this means that you have to do this for every type that BinaryTree could possibly be used for (which is not very practical or scalable, and kind-of defeats the purpose of templates). Also, it will make the cpp very long to compile, but you won't have to recompile that template code again after.

EDIT: Rereading your question I just spotted the obvious:

binaryTree tree();

This is illegal syntax in C++ because it will be interpreted as a function declaration, not a constructor call. This is an infamous "feature" of C++ inherited from C which states that whenever something looks like either a statement (like a constructor call would be) or a declaration (like a function declaration), then it is assumed to be a declaration. So, this code is interpreted as if you are declaring a function called "tree" which takes no parameters and returns an object of type "binaryTree". So the compiler thinks that the type of "tree" is a function, not an object of a class-type, and hence, the error you are getting. To fix it, just remove the () parentheses (the default constructor will be called anyways).

But what I said above is still valid in your case.

Without having code that compiles...

The signature may be incorrect. void insertNode(T);

Seems like you want to insert a node, not a type, which is represented by T?

I had to put the header file code and template code inside above on the int main() in my program, which fixed my problems. I was trying to avoid this, but once I get the program finished I'll try to separate them. Thanks a lot!