Reputation: 3
I am making a BST class with template types for the key, data and a comparison function. I have a function that creates new nodes and returns a pointer to other functions. The problem is, the return type is not valid while using templates. I have created trees previously without templates and returning a type node* wasn't an issue. I'm not sure of what is happening behind the scenes to make the template version not work. The errors I'm getting include:
unrecognizable template declaration/definition
syntax error: missing ';' before '*'
missing type specifier - int assumed. Note: C++ does not support default-int
My class template, node struct and node create function are below:
template <typename KEY, typename VALUE, bool (*COMPARE)(KEY, KEY )>
class BSTROOT {
private:
struct Node {
KEY key;
VALUE value;
Node *left = nullptr;
Node *right = nullptr;
};
Node* createNode(const KEY& key, const VALUE& value);
template <typename KEY, typename VALUE, bool(*COMPARE)(KEY, KEY)> Node* BSTROOT<KEY, VALUE, COMPARE>::createNode(const KEY& key, const VALUE& value) {
Node *temp = new Node;
temp->key = key;
temp->value = value;
return temp;
}
Any tips or information would be appreciated.
Upvotes: 0
Views: 787
Reputation:
I think this will help
template <typename KEY, typename VALUE, bool(*COMPARE)(KEY, KEY)>
struct Node {
KEY key;
VALUE value;
Node *left = nullptr;
Node *right = nullptr;
};
template <typename KEY, typename VALUE, bool(*COMPARE)(KEY, KEY)>
class BSTROOT {
private:
Node* createNode(const KEY& key, const VALUE& value);
};
template<typename KEY, typename VALUE, bool(*COMPARE)(KEY, KEY)>
Node * BSTROOT<KEY, VALUE, COMPARE>::createNode(const KEY & key, const VALUE & value)
{
Node *temp = new Node;
temp->key = key;
temp->value = value;
return temp;
}
Upvotes: 0
Reputation: 372814
The issue here is that the Node*
type is nested inside of the BSTROOT
type, so you need to explicitly indicate that when writing the type of the return value from the function in the implementation. That would look something like this:
template <typename KEY, typename VALUE, bool(*COMPARE)(KEY, KEY)>
typename BSTROOT<KEY, VALUE, COMPARE>::Node*
BSTROOT<KEY, VALUE, COMPARE>::createNode(const KEY& key, const VALUE& value) {
Node *temp = new Node;
temp->key = key;
temp->value = value;
return temp;
}
Here, the extra typename
keyword is necessary because Node
is what's called a dependent type (a type nested inside something that depends on a template parameter).
You don't need to put that long name inside the body of the class because in that context the compiler already knows to look inside of BSTROOT
. Outside of the class, though, the compiler can't tell that you want it to look at the nested Node
type rather than some other global type named Node
.
Upvotes: 1