I am having an issue with implementing a template Linked List class.
I've made linked lists before, but not as a template.
In the .cpp file (implementation) it seems that the member pointer variables aren't being recognized as members and using -> after these pointers doesn't work.
There is no underline of syntax error anywhere near the issue, but when I highlight the variable, the description says "unknown" and the details of the variable
(What's even stranger is that nothing i place in the scope can get the underline syntax error.)
// ListLinked.h
#include <iostream>
using namespace std;
template <typename DataType>
class List {
private:
struct ListNode {
DataType dataItem;
ListNode* next;
};
ListNode* head;
ListNode* cursor;
public:
List(int ignored = 0);
List(const List& other);
List& operator=(const List& other);
~List();
void insert(const DataType& newDataItem);
void remove();
void replace(const DataType& newDataItem);
void clear();
bool isEmpty() const;
bool isFull() const;
void gotoBeginning();
void gotoEnd();
bool gotoNext();
bool gotoPrior();
void showStructure() const;
DataType getCursor() const;
};
//ListLinked.cpp (just the simplest one of the many member functions that use ->)
template <typename DataType>
bool List<DataType>::gotoNext(){
if (cursor->next != NULL) //"next" is not seen as a member pointer variable
cursor = cursor->next;
}
// all the other member functions start with
// template <typename DataType>
// [type] List<DataType>:: {...}
I suspect that something is wrong with my visual express 2010, but i'm not sure
When you use templated class/function, you need to have the whole implementation in source file. Put all the template reference to your .h file as a first move ;)
If you want to keep your header clean without the function code, you can create a file named linkedlist.impl and put in your definition. At the end of your header, before your guard, add #include "linkedlist.impl".
Related
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
Hello I am working on a project for data structures and I am stuck.
The project is to build a templated linked list class and a nested iterator class, inside a headerfile only. I do not understand how to use the iterator class inside of the templated LinkedList class. I am not sure about iterators in general. The methods declared are all needed to run the tests that will be ran. I am currently stuck on initializing 'LinkedList* prev' and next in the constructor. Please help! How do I initialize something that is templated? the compiler wants to know what data type I think? Thanks for your time
The error is on the constructor declaration in the class LinkedList
EDITED "invalid initialization of non-const reference of type 'std::basic_string char&' from an rvalue of type 'int'" is the error message
#ifndef LINKEDLIST_H_
#define LINKEDLIST_H_
#include <iostream>
#include <string>
#include <cstdlib>
using namespace std;
template <typename T> class LinkedList
{
private:
LinkedList<T>* head;
int size;
T element = NULL;
LinkedList<T>* prev;
LinkedList<T>* next;
public:
class Iterator
{
friend class LinkedList<T>;
private:
public:
Iterator();
T operator*() const;
Iterator& operator++();
bool operator==(Iterator const& rhs);
bool operator!=(Iterator const& rhs);
};
LinkedList<T>():prev(0), next(0){} //HERE is the ERROR????////////
Iterator begin() const
{
// Iterator tempIterator = LinkedList<T>();
//
// return tempIterator->front;
return NULL;
}
Iterator end() const{return NULL;}
bool isEmpty() const;
T getFront() const;
T getBack() const;
void enqueue(T newElement)
{
LinkedList<T>* newElem = new LinkedList<T>();
newElem->element = newElement;
if(front == 0)
{
front = newElem;
}
else
{
back->next = newElem;
}
back = newElem;
listSize++;
}
void dequeue()
{
LinkedList<T>* tempElem = new LinkedList<T>();
if(front == 0){
cout << "List is empty!" << endl;
}
else
{
tempElem = front;
front = front->next;
cout << "the element dequeued: " << tempElem->element;
delete tempElem;
}
}
void pop();
void clear();
bool contains(T element) const;
void remove(T element);
};
#endif /* LINKEDLIST_H_ */
The constructor syntax is wrong.
LinkedList():prev(0), next(0){}
This is the correct constructor syntax. Once the template class and parameters are declared, in the template declaration, the name of the template alone, without the parameters, refers to the template itself, inside its scope. Similarly, if you were to explicitly define a destructor, it would be:
~LinkedList() { /* ... */ }
If you wanted to only declare the constructor inside the template declaration:
LinkedList();
and then define it outside of the template declaration, then the correct syntax would be:
template<typename T>
LinkedList<T>::LinkedList() :prev(0), next(0){}
I'm getting the compiler error: error "Node" does not name a type.
This is my header:
#ifndef LINKEDLIST_H
#define LINKEDLIST_H
template <class ItemType>
class LinkedList
{
public:
LinkedList(); // Constructor
bool isEmpty() const; // Checks if list is empty.
int getLength() const; // Returns the amount of times in the list.
bool insert(int index, const ItemType& insertItem); // Inserts an item at index.
bool remove(int index); // Removes item at index.
void clear(); // "clears" the list, but actually sets amount of items to zero.
ItemType getIndex(int index); // Returns the item at a given index.
int find(const ItemType& findItem); // Finds an item, then returns the index it was found.
void printList() const;
private:
struct Node // Struct so I can have my linked list.
{
ItemType item; // Data item.
Node* next; // Pointer to the next node.
};
int itemCount; // Current amount of items in list.
Node* headPtr; // Head/beginning of the list.
Node* getNodeAt(int position) const; // Private method to get position.
};
#include "LinkedList.cpp"
#endif // LINKEDLIST_H
Then my cpp:
#include "LinkedList.h"
#include <iostream>
using namespace std;
// All the other methods, and at the very end...
template<class ItemType>
Node* LinkedList<ItemType>::getNodeAt(int position) const //Error is here.
{
Node* retPtr = headPtr;
int index = 0;
while(index != position)
{
retPtr = retPtr->next;
index++;
}
return retPtr;
}
The error is at the method signature in the cpp file for getNodeAt. From what I've read, it seems the errors come about when an object is referenced that isn't already defined, but I'm not really seeing how I've made that error.
The error is correct: there is no Node type anywhere in your program. However there is a LinkedList<ItemType>::Node type. Use it instead.
Another problem: you should not include LinkedList.cpp in LinkedList.h. And certainly you should not include LinkedList.h in LinkedList.cpp if you do include .cpp file. General approach is to implement all template code in header. If you want to sepatate implementation and include it in header then do not include header in implementation and give it extention different from source code extention to not confuse build system.
// All the other methods, and at the very end...
template<class ItemType>
Node* LinkedList<ItemType>::getNodeAt(int position) const //Error is here.
{
Node* retPtr = headPtr;
int index = 0;
while(index != position)
{
retPtr = retPtr->next;
index++;
}
return retPtr;
}
Node is a member struct of an encompassing struct, so do LinkedList<ItemType>::Node* in the return type as you've not yet entered the LinkedList<ItemType> scope.
Also, if that template function is used by any other file directly (or through another template function), you'll probably have to move it to your header file at one point or you'll get another compiler error.
EDIT: Fixed the error
This is my first time working with templates and am getting nasty syntax errors. I have no idea where the error is since the compiler is telling me I am missing a semi-colon, followed by hundreds of errors. Everything appears fine, however. I am almost certain no semi-colons are missing.
Can anyone help me find this needle in a haystack?? PS The error occurs on the definition of the constructor for the List and says missing ';' before '<' (i.e. the code below)
template <typename T>
class Node
{
template <typename T>
friend class List<T>;
public:
//Default constructor
Node();
//Copy constructor
Node(const Node<T> & copy);
//Overloaded assignment operator
Node<T> &operator=(const Node<T> & rhs);
//Destructor
~Node();
//Methods
T CreateNode(const T & T);
T &getData();
private:
//Data members
T data;
Node * mNext;
};
I can't guarantee it's the only problem, but this certainly looks suspicious:
T &List<T>::Front() const
T &List<T>::Back() const
void Purge();
At a guess, you intended that to declare three separate functions, in which case it is missing a couple of semicolons, and should look more like this:
T &List<T>::Front() const;
T &List<T>::Back() const;
void Purge();
...or, quite possibly:
T &Front() const;
T &Back() const;
void Purge();
Found the error. It was in my node.h file. The code was
friend class List<T>;
I removed the and it worked. :)
I am getting a few errors that I don't know about and have spent entirely to much time pulling my hair out. Here is my Header:
#ifndef MYBSTREE_H
#define MYBSTREE_H
#include "abstractbstree.h"
#include "MyBSTreeFunc.h"
using namespace std;
template<typename T>
class TreeNode
{
public:
T m_data;
TreeNode* m_right;
TreeNode* m_left;
};
template<typename T>
class MyBSTree:public AbstractBSTree<T> //LINE 18
{
private:
TreeNode<T>* m_root;
public:
void MyBSTree();
int size() const;
bool isEmpty() const;
int height() const;
const T& findMax() const;
const T& findMin() const;
int contains(const T& x) const;
void clear();
void insert(const T& x);
void remove(const T& x);
void printPreOrder() const;
void printPostOrder() const;
void print() const;
};
#endif
And my implementation file:
Line 1-6
void MyBSTree()
{
m_root -> m_data = NULL;
m_root -> m_right = NULL;
m_root -> m_left = NULL;
}
Line 13-21
template<typename T>
bool MyBSTree<T>::isEmpty() const
{
if (m_root== NULL)
return true;
else
return false;
}
Line 28-35
template < typename T >
const T& MyBSTree<T>::findMax() const
{
TreeNode* p = m_root;
while(p -> m_right != NULL)
p = p -> m_right;
return p;
}
The error for line 3 in the implementation says 'm_root' was not declared in this scope. But it's cool with lines 4 and 5. I'm guessing because m_data isn't a pointer? I don't know.
Next, Line 14, and 21, and quite a few others say that it expected an initializer before the '<' token. I assume they are all the same issue so I only put a few here.
Finally, it says for line 18 in the header: "template struct MyBSTree redeclared as a different kind of symbol." It then says Line 1 of my implementation is a previous declaration of 'void MyBSTree". I am assuming those go together.
Thanks for all the help.
You need to fix your constructor declaration:
template < typename T >
classMyBSTree
{
... // some stuff
public:
MyBSTree(); // no return type
... // some stuff
};
You alse need to fix your constructor:
template < typename T >
MyBSTree::MyBSTree() // proper ctor definition
{
m_root -> m_data = T(); // use the initializer for that data type
m_root -> m_right = NULL;
m_root -> m_left = NULL;
}
Lines 1-6: You've define a standalone function in the .cpp named void MyBSTree(). This is not part of the class. It's also bad that you named the function the same as your class. It looks like you want this to be your constructor, in which case you need this (I won't include the template stuff, as it's not the issue):
// in .h
class MyBSTree {
public:
MyBSTree(); // No void
}
// in .cpp
// Uses MyBSTree namespace.
MyBSTree::MyBSTree() { /* initialize your pointers etc */ }
This seems to be your main issue, and may fix the other problems too.
The reason the compiler cannot find m_roots is because your function is not part of the class. You would fix this by putting your function into the class scope with operator :: (e.g. myBSTree::myBSTree(){};)
Template functions cannot be placed in separate files from their class, you need to define all of your template class and function in the same file. Move the implementation of your functions into your header file.
Hi I am trying to implement a linked list using templates and ADT. At the moment I have two classes. One is an iterator for linked list and the other is the base class for linked lists that I will use to derive linked list classes from.
When trying to implement two functions that will give me an iterator at the start and end of the list respectivly I get compile error saying "ISO C++ forbids declaration of 'linkedListIterator' with no type"
Here is the code for the definition of the iterator:
#ifndef LINKEDLISTITERATOR_H
#define LINKEDLISTITERATOR_H
#include <stddef.h> //for NULL
#include "nodetype.h"
#include "linkedlisttype.h"
template <class Type>
class linkedListIterator
{
public:
linkedListIterator();
linkedListIterator(nodeType<Type> *ptr);
Type operator*();
linkedListIterator<Type> operator++();
bool operator==(const linkedListIterator<Type>& right) const;
bool operator!=(const linkedListIterator<Type>& right) const;
private:
nodeType<Type> *current;
};
#endif // LINKEDLISTITERATOR_H
Here is the code for the definition of the node Type
#ifndef NODETYPE_H_INCLUDED
#define NODETYPE_H_INCLUDED
//Definition of the node
template <class Type>
struct nodeType
{
Type info;
nodeType<Type> *link;
};
#endif // NODETYPE_H_INCLUDED
Here is the definition of the linkedlist base class:
#ifndef LINKEDLISTTYPE_H
#define LINKEDLISTTYPE_H
#include "nodetype.h"
#include "linkedlistiterator.h"
//Definition of linked list
template <class Type>
class linkedListType
{
public:
const linkedListType<Type>& operator=
(const linkedListType<Type>&);
void initializeList();
bool isEmptyList() const;
void print() const;
int length() const;
void destroyList();
Type front() const;
Type back() const;
virtual bool search(const Type& searchItem) const = 0;
virtual void insertFirst(const Type& newItem) = 0;
virtual void insertLast(const Type& newItem) = 0;
virtual void deleteNode(const Type& deleteItem) = 0;
// this is where the error comes
linkedListIterator<Type> begin();
// and here as well
linkedListIterator<Type> end();
linkedListType();
linkedListType(const linkedListType<Type>& otherList);
~linkedListType();
protected:
int count;
nodeType<Type> *first;
nodeType<Type> *last;
private:
void copyList(const linkedListType<Type>& otherList);
};
#endif // LINKEDLISTTYPE_H
I am new to templates and ADT so trying to wrap my mind around this. Any help will be most appreciated please.
You have two headers which each try to include each other. The result is that, if you #include "linkedlistiterator.h", the definition of linkedListType appears before that of linkedListIterator; hence the error due to linkedListIterator not being declared at that point.
In this case, it looks like the iterator type does not depend on the list type at all, so you can simply remove the #include "linkedlistlype.h" from "linkedlistiterator.h".
Seems that both linkedlisttype.h and linkedlistiterator.h include each other.
That indicates rather close coupling in your mind. You probably want to have LinkedList<T> class and nested LinkedList<T>::Iterator class.