I have the intention to do a program based on a Double Linked Deque where nodes have double links and what i want to do is that each node is a "Document with name and priority" (priority = 1 insert from head, prio. = 2 insert from rear).
Actually my code is like this, but i don't get everything to work with my templates as i don't know how to declare it correctly in the Node.h .
Document.h
template<class T>
class Document
{
private:
T name;
T pri;
public:
Document(T name, T pri);
};
template <class T>
Document<T>::Document(T name, T pri){
this->name = name;
this->pri = pri;
}
Node.h
#include "Document.h"
template <class T> class Node{
public:
Node();
Node(const T& item);
(...other functions...)
private:
Document<T> document; //WHERE MY PROBLEM IS!
Node<T>* next;
Node<T>* previous;
};
template <class T>
Node<T>::Node(const T& item) {
this->document= new Document<T>(item); //Problem with the declaration
this->next = nullptr;
this->previous = nullptr;
}
LinkedDeque.h
#include "Node.h"
#include "Document.h"
template <class T> class LinkedDeque {
public:
LinkedDeque();
void insertFront(const T& element);
void insertRear(const T& element);
(... other functions ...)
private:
Node<T>* front; //Front de la cua
Node<T>* rear; //rear de la cua
int num_elements;
};
template <class T>
void LinkedDeque<T>::insertFront(const T& element){
Node<T>* aux = new Node<T>(element);
(...rest of the function...)
}
Main.cpp
LinkedDeque<Document<string>> deque;
cin >> name >> pri;
Document<string> document(name,pri);
if (pri == "1") {
deque.insertFront(document);
}else {
deque.insertRear(document);
}
The first thing I see is that you declared your constructor as
Document(T name, T pri)
but you are trying to create a document object by just using just an item like
this->document= new Document<T>(item)
so I suggest passing a name and priority to your constructor, that would work.
Related
I get an initialization error for a TreeNode class constructor… This is the function:
TreeNode* a = new TreeNodens; Is the issue here, not sure what I have to add to TreeNode but it needs some type of tweak!
template <typename T>
void ScapegoatST<T>::rebuild(TreeNode<T>* node){
int ns = getHeight(node);
TreeNode<T>* p = node->getParent();
TreeNode<T>* a = new TreeNode<T>[ns]();
TreeNode<T>* r;
packintoArray(node,a,0);
if (p == NULL){
r = buildBalanced(a,0,ns);
r->setParent(NULL);
} else if (p->getRight() == node){
TreeNode<T>* Tr = buildBalanced(a, 0, ns);
p->setRight(Tr);
p->getRight()->setParent(p);
} else {
p->setLeft(buildBalanced(a,0,ns));
p->getLeft()->setParent(p);
}
}
Here is the TreeNode.h:
#ifndef TREE_NODE_H
#define TREE_NODE_H
#include <cstdlib>
#include <iostream>
using namespace std;
template <typename T>
class TreeNode{
public:
TreeNode(T nData);
virtual ~TreeNode();
T getData();
TreeNode<T>* getLeft();
TreeNode<T>* getRight();
TreeNode<T>* getParent();
void setData(T nData);
void setLeft(TreeNode<T>* nleft){left=nleft;};
void setRight(TreeNode<T>* nright){right=nright;};
void setParent(TreeNode<T>* nparent){parent=nparent;};
template <typename S>
friend class ScapegoatST;
private:
T data;
TreeNode<T>* left;
TreeNode<T>* right;
TreeNode<T>* parent;
};
template <typename T>
TreeNode<T>::TreeNode(T nData){
data = nData;
left = NULL;
right = NULL;
}
template <typename T>
TreeNode<T>::~TreeNode(){
delete left;
delete right;
delete parent;
data = NULL;
}
template <typename T>
T TreeNode<T>::getData(){
return data;
}
template <typename T>
void TreeNode<T>::setData(T nData){
data = nData;
}
#endif
I tired creating a constructor for the array initialization but it wasn’t successful.
The issue here is that you've created the constructor TreeNode(T nData), which prevents the constructor with no arguments TreeNode() from being generated, but you call that constructor when you do new TreeNode<T>[ns]().
One solution would be to add a constructor TreeNode(), with a body like so:
template<typename T>
TreeNode<T>::TreeNode() {
left = NULL;
right = NULL;
}
This will mean that constructing a TreeNode with no nData will result in the node's data field being default-initialized (for primitive types, it will contain an undefined value, and for classes it will act like T() was called to construct the data value).
I implemented a linked-list called Node that had a function called freeData where it would perform a delete on the node given and any following nodes.
I wanted to implement it inside my own custom list class as a private member, but came up with this error in Visual Studio 2019:
C2672 'freeData': no matching overloaded function found
C2783 'void custom::freeData(list::Node*&): could not deduce template argument for 'T'
I don't know what to change for my freeData function header to accept a Node* as an argument. I pass the argument pHead in these functions: ~list() and clear().
The previous definition before embedding freeData into the list class was void freeData(Node <T>* &pHead).
#include <iostream>
namespace custom
{
template <class T>
class list
{
public:
list() : numElements(0), pHead(NULL), pTail(NULL) { }
~list() { freeData(pHead); }
void clear() { freeData(pHead); numElements = 0; pHead = NULL; pTail = NULL; }
private:
struct Node;
Node* pHead;
Node* pTail;
int numElements;
};
template <class T>
struct list <T> :: Node
{
Node() : pNext(NULL), pPrev(NULL) {}
Node(const T& t) : data(t), pNext(NULL), pPrev(NULL) {}
T data; // data of type T
Node* pNext; // pointer to next node
Node* pPrev; // pointer to previous node
};
template <class T>
void freeData(typename list <T>::Node*& pHead)
{
}
} // end of namespace
int main()
{
custom::list <int> l1;
l1.clear();
return 0;
}
freedata() is a free-standing function. Unlike class methods, free-standing functions have to be declared before they can be used. But, you can't forward-declare freedata() in this case since its argument depends on a type that needs to know what freedata() is. Catch-22.
To fix that, you could break up the declarations and implementations of the list and Node class, eg:
#include <iostream>
namespace custom
{
template <class T>
class list
{
public:
list();
~list();
void clear();
private:
struct Node
{
Node();
Node(const T& t);
T data; // data of type T
Node* pNext; // pointer to next node
Node* pPrev; // pointer to previous node
};
Node* pHead;
Node* pTail;
int numElements;
};
template <class T>
void freeData(typename list <T>::Node*& pHead)
{
...
}
template <class T>
list<T>::list() : numElements(0), pHead(NULL), pTail(NULL) { }
template <class T>
list<T>::~list() { freeData(pHead); }
template <class T>
void list<T>::clear() { freeData(pHead); numElements = 0; pHead = NULL; pTail = NULL; }
template <class T>
list<T>::Node::Node() : pNext(NULL), pPrev(NULL) {}
template <class T>
list<T>::Node::Node(const T& t) : data(t), pNext(NULL), pPrev(NULL) {}
} // end of namespace
int main()
{
custom::list <int> l1;
l1.clear();
return 0;
}
But really, there is no reason for freedata() to be a free-standing function in this example. It should be a member of the list class instead, eg:
#include <iostream>
namespace custom
{
template <class T>
class list
{
public:
list() : numElements(0), pHead(NULL), pTail(NULL) { }
~list() { clear(); }
void clear() { freeData(pHead); numElements = 0; pHead = NULL; pTail = NULL; }
private:
struct Node
{
Node() : pNext(NULL), pPrev(NULL) {}
Node(const T& t) : data(t), pNext(NULL), pPrev(NULL) {}
T data; // data of type T
Node* pNext; // pointer to next node
Node* pPrev; // pointer to previous node
};
Node* pHead;
Node* pTail;
int numElements;
static void freeData(Node*& pHead)
{
...
}
};
} // end of namespace
int main()
{
custom::list <int> l1;
l1.clear();
return 0;
}
Here's a template (queue) I'm trying to write:
#include <iostream>
using namespace std;
template <typename T>
class Queue
{
friend ostream& operator<< (ostream &, const Queue<T> & );
private:
template<class> class Node;
Node<T> *front;
Node<T> *back;
public:
Queue() : front(0), back(0) {}
~Queue();
bool Empty()
{
return front == 0;
}
void Push(const T& NewEl)
{
Node<T&> *El = new Node<T> (NewEl);
if (Empty())
front=back=El;
else
{
back-> next = El;
back = El;
}
}
void Pop()
{
if (Empty())
cout << "Очередь пуста." << endl;
else
{
Node<T> *El = front;
front = front -> next;
delete El;
}
}
void Clear()
{
while (! Empty())
Pop();
}
};
template <typename T>
class Node
{
friend class Queue<T>;
public:
Node() {next = 0;}
Node(T nd) {nd=node; next=0;}
T& getsetnode(){return node;}
Node<T>*& getsetnext(){return next;}
private:
T front;
T back;
T node;
Node<T> *next;
};
template <class T> ostream& operator<< (ostream &, const Queue<T> & );
int main()
{
Queue<int> *queueInt = new Queue<int>;
for (int i = 0; i<10; i++)
{
queueInt->Push(i);
cout << "Pushed " << i << endl;
}
if (!queueInt->Empty())
{
queueInt->Pop();
cout << "Pop" << endl;
}
queueInt->Front();
queueInt->Back();
queueInt->Clear();
cout << "Clear" << endl;
return 0;
}
At these lines:
Node<T&> *El = new Node<T> (NewEl);
front = front -> next;
delete El;
I get Implicit instantiation of undefined template 'Queue<int>::Node<int>'. What am I doing wrong? After reading this post I tried changing int to const int to see if that was the problem, but apparently it isn't, because I get the same error.
I'm using XCode with LLVM compiler 4.2. When I switch to GCC I get more errors:
template<class> class Node; gets Declaration of 'struct Queue<int>::Node<int>',
Node<T&> *El = new Node<T> (NewEl); gets Invalid use of incomplete type,
and anything dealing with assignment of anything to El can't convert <int&>* to <int>* (but deleting reference doesn't change anything for LLVM).
template <typename T>
class Queue
{
private:
template<class> class Node;
/* ... */
This is a forward declaration of Queue::Node. The latter defined class Node is in the global namespace, so they aren't the same and any usage of Queue::Node will result in an incomplete-type error. Since you don't provide an interface to the interior nodes anyway just scrap the global definition of Node and stick it into Queue:
template <typename T>
class Queue
{
private:
class Node
{
public:
Node() {next = 0;}
/* ... */
};
/* ... */
};
So I've been playing around with Nodes and keep running into this error when I try to test it. If I use Parentheses I get this Error on list. - "Expression must have class type!"
If I don't use Parentheses I get this Error on list, insert and display - "this is inaccessible."
This happens when Declaring my LList in Main(). What's going on and why is this?
My Driver
#include "LList.h"
#include <iostream>
using namespace std;
int main()
{
LList<int> list;
bool test = list.insert(5);
list.display();
return 0;
}
Class LList
#include "Nodes.h"
#ifndef LLIST_H
#define LLIST_H
template<typename TYPE>
class LList
{
Node<TYPE>* front;
LList();
~LList();
bool insert(const TYPE& dataIn);
void display() const;
};
template<typename TYPE>
LList<TYPE>::LList()
{
front = null;
};
template<typename TYPE>
LList<TYPE>::~LList()
{
Node<TYPE>* temp;
while(front)
{
temp = front;
front = fornt -> next;
delete temp;
}
};
template<typename TYPE>
bool LList<TYPE>::insert(const TYPE& dataIn)
{
bool success = false;
Node<TYPE> pBefore = null;
Node<TYPE> pAfter = front;
while(pAfter && PAfter->data < dataIn)
{
pBefore = pAfter;
pAfter = pAfter->next;
}
if(Node<TYPE>* store = new Node<TYPE>)
store->data = dataIn
return success;
};
template<typename TYPE>
void LList<TYPE>::display() const
{
TYPE* temp = front;
while(front && temp->next != null)
{
cout << temp->data << endl;
}
};
#endif
Class Nodes
#ifndef NODES_H
#define NODES_H
template<typename TYPE>
struct Node
{
Node<TYPE>* next;
TYPE data;
Node();
Node(TYPE d, Node<TYPE> n);
};
template<typename TYPE>
Node<TYPE>::Node()
{
data = 0;
next = null;
};
template<typename TYPE>
Node<TYPE>::Node(TYPE d, Node<TYPE> n)
{
data = d;
next = n;
};
#endif
Your errors are a result of your class declaration:
template<typename TYPE>
class LList
{
Node<TYPE>* front;
LList();
~LList();
bool insert(const TYPE& dataIn);
void display() const;
};
The clue is in the error "This is inaccesible." Because you have not given any access modifiers, all of the members of this class default to private. To fix this, you just need to label the public and private sections of your class:
template<typename TYPE>
class LList
{
public:
LList();
~LList();
bool insert(const TYPE& dataIn);
void display() const;
private:
Node<TYPE>* front;
};
With this change, your code should work with or without parentheses at the end of your variable declaration for list.
Okay, guys i have been trying to define a Stack , each node also being of template type but i get dozen different types of errors when the prog tries to compile. i will paste the program which uses a char-type stack and tries to pop letter 'e'
#ifndef STACK_LIST_H
#define STACK_LIST_H
#include "List.h"
using namespace std;
template <class T>
class Stack {
public:
T pop();
void push(T x);
T isEmpty();
T top();
private:
int size;
Node<T> * headNode;
Node<T> * currentNode;
};
#endif
Now the function definitions:
#include <iostream>
#include "Stack_list.h"
using namespace std;
template <class T>
T Stack<T>::pop(){
T x = headNode->get();
Node<T>* p = new Node<T>::Node();
p = headNode;
headNode = headNode->getNext();
delete p;
return x; }
template <class T>
void Stack<T>::push(T x){
Node<T>* newNode = new Node<T>::Node();
newNode->setNext(headNode);
newNode->set(x);
headNode=newNode;
}
template <class T>
int Stack<T>::isEmpty(){
return (headNode ==NULL);}
template <class T>
T Stack<T>::top(){
return headNode->get();
}
now the template class node:
#ifndef LIST_H
#define LIST_H
using namespace std;
/* The Node class */
template <class T>
class Node
{
public:
Node(T here){object=here;};
T get() { return object; };
void set(T object) { this->object = object; };
Node<T>* getNext() { return nextNode; };
void setNext(Node<T>* nextNode) { this->nextNode = nextNode; };
Node<T>* getPrev(){ return prevNode;};
void setPrev(Node<T>* prevNode){this->prevNode=prevNode;};
private:
T object;
Node<T>* nextNode;
Node<T>* prevNode;
};
#endif
and finally the program that evokes the classes:
#include <iostream>
#include "Stack_list.cpp"
using namespace std;
int main(){
Stack <char>s;
s.push("e");
cout<<s.pop();
}
As you can see, this is my first try at template classes. In definitions of Stack::pop() and push(T) it says, "expected type-specifier before ‘Node’"
Node<T>* newNode = new Node() is inconsistent. Is Node a class or a class template? The first time that you mention it, you treat it as a template and instantiate it with T, but the second time you treat it as a class. It can't be both.
Your method definition signatures are:
T Stack<T>::pop()
but they should be
template<typename T>
T Stack<T>::pop()
Also, since Stack uses Node, you have to include Node.h in Stack.h.
Furthermore - in Stack you declared T isEmpty(); but implemented it as int Stack<T>::isEmpty(). Stick to one return type (probably bool is more appropriate here, but int is also OK).
Lastly:
Stack <char>s;
s.push("e");
The template specialization is char, but "e" is a const char*. The correct way would be:
Stack <char>s;
s.push('e'); // <- note the single quotes