Accessing template friend function of class in main. - c++

I am having a hard time finding a simple solution to this. I am implementing an expression tree using the following classes, I declare a friend function of class Tree. My problem comes when I try to get it started in main.
template<class object> class Tree;
template<class object> Tree<object>::expTree(Tree<object> *&T); // ERROR
template<class object>
struct Node
{
object info;
Node *next;
Node<object>():info(0), next(NULL) {}
Node<object>(const object &element, Node *n = NULL):
info(element), next(n){}
};
template<class object>
class Stack
{
public:
Stack();
~Stack();
void makestackempty();
bool stackEmpty() const;
void push(object &item);
void pop (object &item);
void printStack() const;
private:
Node<object> *top;
};
template<class object>
struct TreeNode
{
object info;
TreeNode *right;
TreeNode *left;
TreeNode()
{}
};
template<class object>
class Tree
{
private:
TreeNode<object> *root;
public:
Tree();
~Tree();
Tree(const Tree<object> &rhs); // copy
void operator=(const Tree<object> &rhs);
void copyconst(TreeNode<object> *orig, TreeNode<object> *&rhs);
void makeEmpty(TreeNode<object> *&tree);
bool isEmpty()const;
friend Tree<object> expTree(Tree<object> *&T){
buildTree(T.root);
};
void buildTree(TreeNode<object> *&tree);
void printTree(TreeNode<object> *&tree)const;
};
In main, I get "error: expTree was not declared in this scope."
I also get, " error: expected constructor, destructor, or type conversion before â;â token"
on the second line of this code..
Anyone have any pointers?

template<class object> Tree<object>::expTree(Tree<object> *&T); // ERROR
//^^^^^^^^^^^^^^ cause of the error
This function template is actually a free function, and will be a friend of the class Tree. So it should be written as:
template<class object> expTree(Tree<object> *&T);
That is, remove Tree<object>:: from the declaration. I just realized that it is missing the return type, and I suppose you mean Tree<object> to be the return type (and Tree<object>:: is a typo in your code). If so, then write this:
template<class object> Tree<object> expTree(Tree<object> *&T);
I would like to comment on your style of naming the template parameters and arguments. It is customary to use T, U, V etc for template parameters, not for function argument. So it feels good when you write the declaration as:
template<class T> Tree<T> expTree(Tree<T> *&object);
Well I just swapped the names.

Related

Issue trying to use a template object inside a template class

Consider the following class definitions ...
Node
template <class T> class Node {
private :
T* data;
Node<T>* next;
public :
Node(T* data);
void setData(T* data);
T* getData();
void setNext(Node<T>* next);
Node<T>* getNext();
};
Linked List
template <class T> class LinkedList {
private :
Node<T>* start;
public :
LinkedList();
void add(Node<T>* node);
bool isEmpty();
};
Main
#include "Foo.h"
int main() {
Foo foo();
Node<Foo> node(&foo);
LinkedList<Foo> linkedList();
linkedList.add(&node);
return 0;
}
When it is compiled it throws the following error...
Request for member 'add' in 'linkedList', which is of non-class type 'LinkedList<Foo>()'
I am quite inexperienced making use of templates, so any help would be greatly appreciated.
Foo foo(); and LinkedList<Foo> linkedList(); are not variables but are function prototypes.
Please use Foo foo; and LinkedList<Foo> linkedList; instead.
You can also use Foo foo = Foo(); and LinkedList<Foo> linkedList = LinkedList<Foo>(); to make it clear that the constructors are called.

what is wrong with the template function parameter

Hi I am new to templates. Just want to know how to compile the program correctly.
template<class t>
class node{
public:
t val;
node(t v):val(v){}
};
template<class t>
class stack{
private:
stack *next;
static stack *head;
static int top;
public:
void push(node *n);
node* pop();
};
template<class t>
int stack<t>::top=0;
template<class t>
stack<t>* stack<t>::head=NULL;
template<class t>
void stack<t>::push(node<t>* n) //Error the push function is not defined properly
{
}
int main(int argc, char *argv[])
{
node<int> n1(5);
return 0;
}
The program gives error
stack<t>::push' : redefinition; different basic types
nw.cpp(14) : see declaration of 'stack<t>::push'
Thanks in advance
The class template node needs template arguments
Use node<t> at :
void push(node<t> *n); and node<t>* pop(); and according at implementation
The declaration:
void push(node *n);
should be:
void push(node<t> *n);
public: void push(node *n);
should be
public: void push(node<t> *n);
node is a class template so its template arguments are needed even in the declaration:
void push(node<n> *n);
node<t>* pop();
The only scenario in which you can leave the template arguments out in a parameter declaration is when the declaration appears in the class scope itself. In such a situation node is referred to as the injected class name.
Also, as the comments point out, head and top shouldn't be static data members. This inhibits the creation of independent stack instances and can cause a lot of confusion when they're being used. Instead, make them non-static data members so they only refer to the instance being used.

problems inheriting from a c++ template class

So I'm trying to work out how inheritance works when templates are in the mix. Most compilers really don't seem to have this figured out yet, so I'm having a little syntax difficulty. All the weird includes in SkipNode.h are from trying to get eclipse to stop yelling at me. I'm getting a syntax error when trying to declare the constructor in SkipNode.h, so any help here would be useful.
Here is node.h
#ifndef NODE_H_
#define NODE_H_
template<class T>
class Node
{
public:
Node(Node<T>* next, Node<T>* prev, T item);
virtual ~Node();
Node* getPrev() { return prev;};
Node* getNext() { return next;};
Node* getItem() { return item;};
void setItem(T item){Node<T>::item = item;};
void setNext(Node* next){Node<T>::next = next;};
void setPrev(Node* prev){Node<T>::prev = prev;};
private:
Node* next;
Node* prev;
T item;
};
Here is SkipNode.h, where skipnode inherits from Node.
#include "Node.h"
#include "Node.cpp"
#include "SkipNode.h"
#include "SkipNode.cpp"
template <class T>
class SkipNode: public Node
{
public:
SkipNode(Node<T>* next, Node<T>* prev, Node<T>* child, T item) : Node(next, prev, item);
virtual ~SkipNode();
Node* getChild(){return child;};
void setChild(Node* child){SkipNode::child = child;};
private:
Node *child;
};
#endif /* SKIPNODE_H_ */
Node is a template, you should pass in template parameter
template <class T>
class SkipNode: public Node<T>
// ^^^
Also you need to provide SkipNode constructor definition as you have provided member iniatilizer list.
update:
SkipNode(Node<T>* next, Node<T>* prev, Node<T>* child, T item)
: Node(next, prev, item);
To:
SkipNode(Node<T>* next, Node<T>* prev, Node<T>* child, T item)
: Node(next, prev, item)
{
}
You're missing an #endif in node.h and you need to provide the template parameter to your base class:
template <class T>
class SkipNode : public Node< T >
....
This level of indirection exists to allow inheritance from a template class by a class that has different (or zero) template parameters. For instance:
class Foo : public Node< int >

C++ template class with template class member

What is the current syntax for writing a template member class parameter inside a template class.
This is what I been trying to do:
template <class T>
class Node
{
public:
Node(); // constructor
Node(const Node<T> &); // copy constructor
~Node(); // destructor
T value;
Node *next;
};
template <class T>
class Linked_list
{
public:
Linked_list(); // constructor
Linked_list(const Linked_list<T> &); // copy constructor
~Linked_list(); // destructor
T pop();
void push(T value);
T top();
bool is_empty();
void clear();
private:
Node<T> *head; // COMPILER ERROR
};
Why this is a compiler error?
Node<T> *head; // COMPILER ERROR
Perhaps when you call:
Node<T> *head;
T is not an object type, and it doesn't know how to construct that. Try:
Node<std::string> *head;
or something like that. T is not an object type, it is just like a variable name, except it is actually a variable type within the class Node and LinkedList.

Holding a generic type's instance - C++

I have a tree_node class and a tree class.
template<typename T>
class tree_node
{
public:
tree_node(const std::string& key_, const T& value_)
: key(key_), value(value_)
{
}
private:
T value;
std::string key;
};
template<typename T>
class tree
{
public:
tree() : root(new tree_node<T>("", ???)) { }
private:
tree_node<T>* root;
};
tree_node expects an instance of T when creating. How can I pass it in the ??? place? I can say T(), but it will work only if T has a parameterless constructor. I can't have a parameterless constructor for tree_node as it won't compile if T doesn't have a parameterless constructor.
I am looking for a way to design tree_node which can hold all types correctly including pointer types.
Edit
After trying various methods, I found that boost::optional is helpful in this case. I can make the T value into boost::optional<T> value. This will solve the empty constructor issue. So I can have another constructor overload of tree_node which just takes a key. This can be used by the root node. Is this the correct way to go?
Thanks..
Init root value should be zero. If you push new node you obviously know value.
template<typename T>
class tree
{
public:
tree() : root(0) { }
void push (const std::string& key, const T & t) {
if (root == 0) {
root = new tree_node<T>(key, t);
} else {
// Make complex tree
}
}
private:
tree_node<T>* root;
};
Add
If you use suffix tree you should make two types of vertices:
enum NodeType { EMPTY_NODE, VALUE_NODE };
class base_tree_node
{
public:
base_tree_node() :parent(0), left(0), right(0) {}
virtual NodeType gettype() = 0;
protected:
base_tree_node* parent;
base_tree_node* left;
base_tree_node* right;
};
class empty_tree_node : base_tree_node
{
virtual NodeType gettype() { return EMPTY_NODE; }
}
template<typename T>
class tree_node : base_tree_node
{
public:
tree_node(const std::string& key_, const T& value_)
: key(key_), value(value_)
{
}
virtual NodeType gettype() { return VALUE_NODE; }
private:
T value;
std::string key;
};
tree( const T & t ) : root(new tree_node<T>("", t )) { }
I have once done a linked list (just for fun) which needed a sentinel node not meant to hold any data, and I had the following structure:
struct BaseNode
{
BaseNode* next;
BaseNode(BaseNode* next): next(next) {}
};
template <class T>
struct Node: public BaseNode
{
T data;
Node(const T& data, BaseNode* next): BaseNode(next), data(data) {}
};
template <class T>
struct List
{
BaseNode* head;
List(): head(new BaseNode(0)) {}
void add(const T& value)
{
Node<T>* new_node = new Node<T>(value, head->next);
head->next = new_node;
}
T& get_first()
{
assert(head->next);
return static_cast<Node<T>*>(head->next)->data;
}
//...
};
The class itself must make sure it gets necessary casts right and doesn't try to cast head or root itself to Node<T>.
A tree node should have (or be) a collection of child nodes. A tree should have (or be) a collection of root nodes. Both those collections should be the same type. Very simply:
template <class T>
class NodeCollection
{
std::vector<Node<T> *> nodes;
public:
// any operations on collection of nodes
// copy ctor and destructor a must!
};
template <class T>
class Node : public NodeCollection<T>
{
T value;
public:
// ctor
// access to value
};
template <class T>
class Tree : public NodeCollection<T>
{
public:
// ctor
};
This way the shared definition of Tree and Node is actually in NodeCollection, and so Tree doesn't need to carry a dummy value.