I am trying to create a Doubly Linked List and respective node class and am having an issue trying to add the data types of head and tail to my IntDLList class. I'm not quite sure what I missed, but an error is occurring stating that both head and tail were not declared, and that my Node class does not take a type. Any help is appreciated!
Edit: This does not seem to be a duplicate question, I looked at the other answers and trying to resolve an invalid use of incomplete type did not solve the same issue as my name type error.
IntDLList
using namespace std;
template <class T>
class IntDLList {
public:
IntDLList() {
head=tail=0; // error: 'head' was not declared in this scope (& same for tail)
}
~IntDLList();
int isEmpty() {
return head==0; // error: 'head' was not declared in this scope
}
void addToDLLHead(const T&);
void addToDLLTail(const T&);
T deleteFromDLLHead();
T deleteFromDLLTail();
void deleteDLLNode(const T&);
bool isInList(const T&) const;
void showList();
private:
IntDLLNode<T> *head, *tail; //error: IntDLLNode does not name a type
};
IntDLLNode
using namespace std;
template<class T>
class IntDLLNode {
friend class IntDLList;
public:
IntDLLNode() {next = prev = 0;}
IntDLLNode(const T& el, IntDLLNode *n = 0, IntDLLNode *p = 0) {
info = el;
next = n;
prev = p;
}
protected:
T info;
IntDLLNode<T> *next,*prev;
private:
};
Related
This question already has answers here:
Why do I have to access template base class members through the this pointer?
(3 answers)
Derived template-class access to base-class member-data
(3 answers)
Closed 3 years ago.
I'm coding a simple LinkedList class that is a child class to an abstract List class. After finishing the List class I started to code the LinkedList class, and I noticed that the compiler would not let me access the protected variables from the members of the List class directly, even though LinkedList is a child class of List. When I do not add the "this->" pointer before one of List's variables, I get an error that says the variable is not declared in the scope. I'm sure there is a simple explanation for this, but I can't figure out why the two protected variables in my List class and its members are not accessible from the members of the LinkedList class.
List:
template<typename T>
class List {
protected:
unsigned int numElements;
Node<T>* head;
public:
List();
~List();
virtual void append(T x) = 0;
virtual T remove() = 0;
virtual bool isEmpty();
};
template<typename T>
List<T>::List() {
numElements = 0;
head = NULL;
}
template<typename T>
List<T>::~List() {
while(NULL != head) {
Node<T>* newHead = head->getNext();
delete head;
head = newHead;
}
}
template<typename T>
bool List<T>::isEmpty() {
if (numElements)
return false;
return true;
}
LinkedList with one member example:
template<typename T>
class LinkedList: public List<T> {
public:
void append(T x);
T remove();
void append_tail(T x);
void insert(T x, int pos);
T remove_at(int pos);
void print();
int getNumElements();
};
template<typename T>
void LinkedList<T>::append(T x) {
// create a new node with its next as the head
Node<T>* appendNode = new Node<T>(x, this->head);
// set the head to this new node
this->head = appendNode;
this->numElements++;
}
Node class that is included (not very relevant)
#ifndef NODE_H
#define NODE_H
template<typename T>
class Node {
private:
T value;
Node * next;
public:
Node(T v, Node * n);
T getValue() const;
Node * getNext() const;
void setNext(Node * p);
};
template<typename T>
Node<T>::Node(T v, Node * n) {
value = v;
next = n;
}
template<typename T>
T Node<T>::getValue() const {
return value;
}
template<typename T>
Node<T>* Node<T>::getNext() const {
return next;
}
template<typename T>
void Node<T>::setNext(Node * n) {
this->next = n;
}
#endif
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:
Understanding templates in c++
(2 answers)
Closed 7 years ago.
I'm implementing a singly linked list. Here's the node class
template <typename T> class node{
friend class slist<T>;
public:
explicit node():data(0), next(NULL){}
private:
T data;
node<T> *next;
};
And here's the list class.
template<typename T> class slist{
public:
slist():head(NULL){}
bool empty(){
return head == NULL;
}
void add_front(const T& data){
if(head == NULL){
node<T>* n = new node<T>();
n->data = data;
n->next = NULL;
head = n;
return;
}
node<T>* n = new node<T>();
n->data = data;
n->next = head;
head = n;
}
void remove_front(){
if(head == NULL) return;
node<T>* old = head;
head = old->next;
delete old;
}
void print_list(){
if(head == NULL) return;
while(!empty()){
std::cout<<head->data<<std::endl;
head = head->next;
}
}
~slist(){
while(!empty()) remove_front();
}
private:
node<T>* head;
};
The implementation works perfectly fine if I declare the members in the node as public. However the moment I declare them private and make the slist a friend class, I get the following error.
In file included from src.cpp:3:
./slist.hpp:5:28: error: redefinition of 'slist' as different kind of symbol
template<typename T> class slist{
^
./node.hpp:4:15: note: previous definition is here
friend class slist;
I can obviously find other implementation of single linked list, but I'm trying to understand what's going wrong here. So please refrain from unsolicited advice as "google it". Thanks.
You need to forward declare the List class as a template class:
#include <iostream>
template<typename T> class List; //<< fwd decl
template<typename T> class Node {
int i;
public:
friend class List<T>; //<< usage same as you have now
Node() : i(123) {}
int value() { return i; }
};
template<typename T> class List { //<< definition
public:
List(Node<T>* node) { node->i++; }
};
int main() {
Node<int> node{};
List<int> list{&node};
std::cout << node.value() << "\n";
}
http://ideone.com/2RUWgj
The friend class declaration needs it's own template parameter declaration without shadowing the enclosing classes template parameters:
template<typename U> class slist; // Forward declare slist
template <typename T>
class node{
template<typename U> // <<<<<
friend class slist<U>;
// ^ <<<<<
// ...
};
This is the Contents of Graph.h without the header protects and other Functions
template <class T> class Node{
public:
T data;
Node<T> *NextNode;
public:
Node();
Node(T a);
T getValue();
void setValue(T a);
void chainNode(Node<T> a);
void chainNode(Node<T> *a);
Node<T> getNextNode();
void unchainNode();
};
//related methods
template <class T> Node<T>::Node(){
data = NULL;
NextNode = NULL;
}
template <class T> void Node<T>::chainNode(Node<T> a){
NextNode = NULL;
NextNode = &a;
}
template <class T> void Node<T>::chainNode(Node<T> *a){
NextNode = NULL;
NextNode = a;
}
template <class T> class List{
public:
Node<T> *Head;
List(Node<T> a);
void AddInFront(Node<T> a);
void AddInFront(Node<T> *a);
void Append(Node<T> a);
bool Remove(Node<T> a);
bool Remove(T a);
bool Contains(T a);
bool DeleteList();
};
//Only working method of List
template <class T> List<T>::List(Node<T> a){
Head = &a;
}
// Error occurs in this Function
template <class T> List<T>::AddInFront(Node<T> a){
a.chainNode(Head);
Head = NULL;
Head = &a;
}
And this is My Main
#include<iostream>
#include"Graph.h"
int main(){
Node<int> a = Node<int>(20);
List<int> d = List<int>(a);
Node<int> b = Node<int>(20);
d.AddInFront(b);
}
And here is my error
error C4430: Missing type specifier - int assumed . Note: C++ does not support default- int
My compiler (MSVS 11) tells me I have a C4430 error at the end of the AddInFront function and by end I mean it is saying the line with anything but the end curly bracket has the error.I have tried every thing under the moon to try to get rid of this error but I just can't seem to fix it.
You forgot to specify the return type in the definition of your AddInFront() function:
template <class T> void List<T>::AddInFront(Node<T> a) {
// ^^^^
// This was missing
a.chainNode(Head);
Head = nullptr;
Head = &a;
}
Also notice, that the copy-initializations belows:
Node<int> a = Node<int>(20);
List<int> d = List<int>(a);
Node<int> b = Node<int>(20);
Are unnecessary. Rather use direct initialization:
Node<int> a(20);
List<int> d(a);
Node<int> b(20);
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.