Class property includes instance of a template class (error C3857) - c++

I am implementing a binary tree class that is almost identical to this one. However, in my task, the node struct must be a templated structure. Therefore I changed struct node to:
template <typename T>
class node {
public:
T data;
node<T> *left, *right;
}
so far so good, until I added a node instance to btree as a member variable:
class btree {
// ......
private:
template <typename T>
node<T> *root = NULL; // error
}
error message says
C3857: multiple template parameter lists are not allowed.
I tried to move root = NULL to btree's default constructor, does not work either.

You cannot have a templated variable declaration. There would be no way to specify the type to use for the variable. You can either make btree a template and use that type for the node
template<typename T>
class btree {
// ......
private:
node<T> *root = NULL; // error
}
or specify what type of node you want in btree
class btree {
// ......
private:
node<some_type> *root = NULL; // error
}

Related

C++ class pointer I.e node*

In c++ liked list Why we have to write node pointer like node* without specifying int, double etc. and we can also declare new node pointers in main without using any node class declaration.
class Node {
public:
int data;
Node* next;
};
If its any different kind of pointer then what it is called?
In your code
class Node {
public:
int data;
Node* next;
};
there is only one kind of node, and it has an int for data. That is why you don't need to write Node<int> or Node<double>. But you could change your code
template <typename T>
class Node {
public:
T data;
Node<T>* next;
};
This is called a template, and instead of only having an int for the data you can have any type. But now you have to say what that type is when you declare a variable. E.g.
Node<double>* ptr = new Node<double>();

Inheriting from a class but using a subclass of an attribute

I have to implement a Red/Black tree (RBTree) in C++, inheriting from a Binary Search Tree (BSTree) class I already created.
The BSTree class contains a Node pointer (Node is a class I created for BSTree) to the tree root.
I want to create a Node subclass called "RBTNode", which contains color attribute and related methods (so RBTNode is subclass of Node), then I want to create the RBTree class inheriting from BSTree, but with the new RBTNode instead of the standard Node.
The structure would be as follows:
BSTree contains Node;
RBTNode is subclass of Node;
RBTree is subclass of BSTree;
RBTree contains RBTNode;
How could I achieve that?
As suggested by Jarod42 in the comments, you can achieve this by making the node type a template parameter for the BSTree class.
Say you have these two node classes:
template<typename KeyT>
class BSNode {
public:
KeyT key;
// ...
};
template<typename KeyT>
class RBNode : public BSNode<KeyT> {
public:
bool color;
};
Then you could add a node type template parameter to BSTree and make it BSNode by default. You can then use RBNode while inheriting in RBTree.
template <typename KeyT, typename NodeT = BSNode<KeyT>>
class BSTree {
protected:
NodeT *root;
};
template <typename KeyT>
class RBTree : public BSTree<KeyT, RBNode<KeyT>> {
// root will be of type RBNode<KeyT>* here
};

Alternative to template variables?

I'm building a binary search tree. As the generic person I am, I want to allow all types to be able to act as keys to nodes in the tree.
So I came up with the following:
class foo
{
private:
template<class T>
struct node
{
T key;
node* left;
node* right;
};
node<>* _root; //point of interest
public:
//.....
template<class T>
void insert(const T& key);
};
As I insert the nodes into the tree, I can create node objects according to the type of the key, but I don't know how to declare the _root in such a way (when using insert on an empty tree, I can easily pick the type for _root).
I believe C++14's template variables can help me here, but unfortunately MSVC's compiler hasn't implemented that feature yet.
Question: How do I declate _root in the most generic way? How did people do it in the past?
Just storing nodes is not a problem:
class foo
{
struct node
{
virtual ~node() {}
node * left;
node * right;
}
template<typename T>
struct key_node: node
{
T key;
~value_node() {}
}
node *root;
};
The problem will come when you want to access the key value within a node (because you will need to store the type information somehow).
Alternately, you can use boost::any instead of a T template:
class foo
{
struct node
{
boost::any key;
node * left;
node * right;
}
node *root;
};
... and use the interface of boost::any to get the value of they key (but even here you will probably need information on the type stored in any before you can access it in a generic way).

Template and BST

The template declaration is:
template <typename DataType>
class BST
and the error that I keep getting is
bst.h(101) : see reference to class template instantiation 'BST::BinNode' being compiled
bst.h(183) : see reference to class template instantiation 'BST' being compiled
I think my syntax may be wrong, but I'm not sure what about it is. Could somebody push me into the right direction. I just cannot get it to compile. Class BinNode is a private class of the main class BST. The line the error is referring too is DataType BinNode::treeheight(BinNode * p)
private:
/***** Node class *****/
class BinNode
{
public:
DataType data;
BinNode * left;
BinNode * right;
DataType treeheight(BinNode * p);
template <typename DataType>
DataType BinNode::treeheight(BinNode * p)
{
if(p != 0)
{
int heightl = treeheight(p->left);
int heightr = treeheight(p->right);
}
if(heightl > heightr)
return heightl;
else
return height r;
}
When defining the member function (outside the class, that is), you need to qualify the member function definition as Node<DataType>::BinNode::treeheight(…) {…} since BinNode is a nested class of Node.

How do I change a class to a template class?

I need to change the first line to : template <class T> class Node{
class Node {
private:
double data;
Node* next;
public:
Node(double);
virtual ~Node(); //for later use of polymorphismi, review the topic again
friend class Stack; // allows dStack for private member access
};
Node::Node(double data) {
this->data = data;
next = 0;
}
Node::~Node() {
}
but i am unsure of all the internal work i need to change. Do i just need to change the private data member and the public Node function?
I think what you are looking for is something along the lines of the following:
template<typename T>
class Node
{
private:
T data;
Node* next;
public:
Node(const T& d);
virtual ~Node();
// ... etc
};
Note that you will either need to implement the template class inline, in the same file, or include the implementation at the bottom of the header file.
The point is that you change your class so that it can be used for other types except double, for example int, float etc in the same way. If we think of it in more abstractly, you need to use the class for objects of type T, where T can be any of the types mentioned above (or even more).
So, in general, you need to put template <class T> (Setting it as a template class) before your class and replace double with T type.
for class declaration:
template<typename T>
class Node
for class functions implementation:
template<typename T>
Node<T>::Node()