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
Related
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;
}
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.
Everything was working before I introduced templates to my code
EDIT:
Here is the problem to which I was able to narrow it down, thanks to your tips:
In file included from main.cpp:4:
stack.cpp: In member function void Stack<TYPE>::push(Stack<TYPE>&, TYPE)':
stack.cpp:35: error:node' is not a type
I wonder if a similar problem could appear later in the pop function, but it seems like it does not.
I'm confused as to why it seems to insist that node is not a type.
EDIT#2:
this statement in the main.cpp file is now causing trouble. I have moved all the definitions out of stack.cpp to stack.h. After this Stack<int> list;my compiles says Segmentation fault (core dumped).
stack.h:
#include <iostream>
using namespace std;
template <typename TYPE>
struct node {
TYPE data;
node<Type> *next;
node(){
data = NULL;
next = NULL;
}
~node(){
if (data!=0)
delete next;
}
explicit node(int i){
data = i;
}
};
template <typename TYPE>
class Stack {
private:
node<TYPE> *top;
void init();
public:
Stack(); // default constructor
virtual ~Stack(); // destructor
bool empty();
void push(Stack&,TYPE);
TYPE pop(Stack&);
int peek();
void clear();
ostream& printf(ostream&, node<TYPE> *);
ostream& print(ostream&);
ostream& sequentialPrint(Stack&,ostream&);
ostream& reversePrint(Stack&,ostream&);
friend ostream& operator<<(ostream&, Stack&);
};
stack.cpp:
template <typename TYPE>
void Stack<TYPE>::push(Stack<TYPE> &s, TYPE i) {
node<TYPE> * n = new node(i);
n->next = top;
top = n;
}
template <typename TYPE>
TYPE Stack<TYPE>::pop(Stack<TYPE> &s){
if (empty()) {
cerr<<"Stack is empty \n";
}
TYPE temp = s.top->data;
top = top->next;
return temp;
}
friend ostream& operator<<(ostream&, Stack&); is not needed
you can't define template methods in cpp file. Every element of template which is template parameter depended must be defined in header file.
I have a header file for a program that utilizes singly linked list. The data that is originally stored in the nodes were integers, however, in an attempt to use the template class, I tried to convert the Node class and AnyList class to template classes; however, when I compile, an error message that says "'Node": use of class template requires template argument list" appears. I've seen examples of template classes, but there's a bit of confusion since I'm trying to make two template classes in one header file.
#ifndef ANYLIST_H
#define ANYLIST_H
#include<iostream>
#include <string>
using namespace std;
template <typename T>
class Node
{
public:
Node() : data(0), next(NULL) {}
Node(T& theData, Node *newNext) : data(theData), next(newNext){}
Node* getNext() const { return next; }
T getData( ) const { return data; }
void setData(T& theData) { data = theData; }
void setNext(Node *newNext) { next = newNext; }
~Node(){}
private:
T data;
Node *next; //pointer that points to next node
};
template <typename T>
class AnyList
{
friend ostream& operator<<(ostream& out, const AnyList<T>& theList);
public:
AnyList();
void insert(const T& elem);
int getNumOfElem() const;
void destroyList();
~AnyList();
private:
Node *first;
int count;
};
#endif
Simply put, Node<> and List<> are different templates. So you need to forward the template parameter from List to Node.
Replace
Node *first;
By
Node<T> *first;
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Why do I get “unresolved external symbol” errors when using templates?
LinkedList.h
#ifndef LINKEDLIST_H
#define LINKEDLIST_H
#include<iostream>
template<class T> class LinkedList;
//------Node------
template<class T>
class Node {
private:
T data;
Node<T>* next;
public:
Node(){data = 0; next=0;}
Node(T data);
friend class LinkedList<T>;
};
//------Iterator------
template<class T>
class Iterator {
private:
Node<T> *current;
public:
friend class LinkedList<T>;
Iterator operator*();
};
//------LinkedList------
template<class T>
class LinkedList {
private:
Node<T> *head;
public:
LinkedList(){head=0;}
void push_front(T data);
void push_back(const T& data);
Iterator<T> begin();
Iterator<T> end();
};
#endif /* LINKEDLIST_H */
LinkedList.cpp
#include "LinkedList.h"
#include<iostream>
using namespace std;
//------Node------
template<class T>
Node<T>::Node(T data){
this.data = data;
}
//------LinkedList------
template<class T>
void LinkedList<T>::push_front(T data){
Node<T> *newNode = new Node<T>(data);
if(head==0){
head = newNode;
}
else{
newNode->next = head;
head = newNode;
}
}
template<class T>
void LinkedList<T>::push_back(const T& data){
Node<T> *newNode = new Node<T>(data);
if(head==0)
head = newNode;
else{
head->next = newNode;
}
}
//------Iterator------
template<class T>
Iterator<T> LinkedList<T>::begin(){
return head;
}
template<class T>
Iterator<T> Iterator<T>::operator*(){
}
main.cpp
#include "LinkedList.h"
using namespace std;
int main() {
LinkedList<int> list;
int input = 10;
list.push_front(input);
}
Hi, I am fairly new at c++ and I am trying to write my own LinkedList using templates.
I followed my book pretty closely and this is what I got. I am getting this error though.
/main.cpp:18: undefined reference to `LinkedList::push_front(int)'
I have no clue why, any ideas?
You are using templates in your Program. When you use templates, you have to write the code and the headers in the same file because the compiler needs to generate the code where it is used in the program.
You can do either this or include #inlcude "LinkedList.cpp" in main.cpp
This question might help you.
Why can templates only be implemented in the header file?