I'm able to implement a template doubly linked list with some basic functions along with data inside of it. Then I proceed to implement an iterator to get access to the data inside the nodes of the linked list. When I implement the iterator, there are no compile-time errors shown in the iterator files. However, I've encountered problems when I try to use the operations of the iterator in main.cpp file(the != operator show the error: Invalid operands to binary expression) Was there something wrong with my implementation of the iterator? Can you help me with this?
LinkedList.h:
//
// Created by baoto on 9/29/2020.
//
#ifndef LINKEDLIST_TEMPLATE_LINKEDLIST_H
#define LINKEDLIST_TEMPLATE_LINKEDLIST_H
#include <iostream>
#include "Node_iterator.h"
#include "Node.h"
using namespace std;
template <class T>
class LinkedList {
private:
Node<T>* head;
Node<T>* tail;
unsigned int size = 0;
Node<T>* find (const T& item);
public:
typedef Node_iterator<T> iterator;
iterator begin();
iterator end();
void remove(Node<T>* node);
bool isEmpty();
void remove(const T& item);
int givelist_size();
void push_back(const T &item);
void push_front(const T &item);
void insertAfter(T search, T item);
void insertBefore(T search, T item);
LinkedList();
void clearList();
template<class S>
friend ostream& operator<<(ostream& out, const LinkedList<S> &list)
{
for (Node<T>* i = list.head; i != nullptr; i = i->next)
{
out << i->data << endl;
}
return out;
}
};
#include "LinkedList.cpp"
#endif //LINKEDLIST_TEMPLATE_LINKEDLIST_H
LinkedList.cpp:
//
// Created by baoto on 9/29/2020.
//
#ifndef LINKEDLIST_TEMPLATE_LINKEDLIST_CPP
#define LINKEDLIST_TEMPLATE_LINKEDLIST_CPP
#include "LinkedList.h"
template <class T>
void LinkedList<T>::clearList() {
Node<T>* walker;
for (walker = head; walker != nullptr; walker = walker->next)
{
Node<T>* deleted = walker;
delete deleted;
}
head = tail = nullptr;
size = 0;
}
template<class T>
bool LinkedList<T>::isEmpty() {
return (head->next == nullptr);
}
template<class T>
int LinkedList<T>::givelist_size() {
return this->size;
}
template <class T>
void LinkedList<T>::remove(Node<T> *node) {
if (node != head && node!= tail)
{
node->next->prev = node->prev;
node->prev->next = node->next;
delete node;
}
else if (size ==1)
{
delete head;
head = nullptr;
tail = nullptr;
}
else if (node == head)
{
head = head->next;
delete head->prev;
head->prev = nullptr;
}
else if (node == tail)
{
tail = tail->prev;
delete tail->next;
tail->next = nullptr;
}
size--;
}
template <class T>
LinkedList<T>::LinkedList(): head(nullptr), tail(nullptr)
{
}
template <class T>
void LinkedList<T>::push_back(const T &item) {
Node<T>* temp = new Node<T>;
temp->data = item;
temp->prev = tail;
temp->next = nullptr;
if (tail == nullptr)
{
tail = temp;
head = temp;
} else{
tail->next = temp;
tail = temp;
}
size++;
}
template <class T>
void LinkedList<T>::push_front(const T &item) {
Node<T>* temp = new Node<T>;
temp->data = item;
temp->next = head;
temp->prev = nullptr;
if (head == nullptr) {
tail = temp;
head = temp;
}
else
{
head->prev = temp;
head = temp;
}
size++;
}
template <class T>
Node<T>* LinkedList<T>::find(const T &item) {
Node<T>* walker;
for (walker = head; walker != nullptr; walker = walker->next)
if (walker->data == item)
return walker;
return nullptr;
}
template <class T>
void LinkedList<T>::insertAfter(T search, T item) {
Node<T>* prevNode;
prevNode = find(search);
if(prevNode != nullptr)
{
Node<T>* temp = new Node<T>;
temp->data = item;
temp->next = prevNode->next;
prevNode->next = temp;
temp->prev = prevNode;
if (temp->next != nullptr)
prevNode->next->prev = temp;
else
{
temp = tail;
}
}
size++;
}
template<class T>
void LinkedList<T>::insertBefore(T search, T item) {
Node<T>* nextNode;
nextNode = find(search);
if (nextNode != nullptr)
{
Node<T>* temp = new Node<T>;
temp->data = item;
temp->prev = nextNode->prev;
nextNode->prev = temp;
temp->next = nextNode;
if (temp->prev != nullptr)
{
temp->prev->next = nextNode;
} else
{
head = temp;
}
}
size++;
}
template <class T>
typename LinkedList<T>::iterator LinkedList<T>::begin() {
iterator temp(head);
return temp;
}
template <class T>
typename LinkedList<T>::iterator LinkedList<T>::end() {
iterator temp(nullptr);
return temp;
}
#endif
Node_iterator.h:
//
// Created by baoto on 10/9/2020.
//
#ifndef LINKEDLIST_TEMPLATE_NODE_ITERATOR_H
#define LINKEDLIST_TEMPLATE_NODE_ITERATOR_H
#include <iterator>
#include "Node.h"
template <class T>
class Node_iterator:public std::iterator<std::forward_iterator_tag,T> {
private:
Node<T>* current;
public:
T&operator*();
Node_iterator operator++(int);
Node_iterator& operator ++();
Node_iterator operator --(int);
Node_iterator& operator --();
Node_iterator();
Node_iterator(Node<T>* n);
bool operator !=(const Node_iterator* n) const;
bool operator == (const Node_iterator* n) const;
};
#include "Node_iterator.cpp"
#endif //LINKEDLIST_TEMPLATE_NODE_ITERATOR_H
Node_iterator.cpp:
//
// Created by baoto on 10/9/2020.
//
#ifndef LINKEDLIST_TEMPLATE_NODE_ITERATOR_CPP
#define LINKEDLIST_TEMPLATE_NODE_ITERATOR_CPP
#include "Node_iterator.h"
template <class T>
T& Node_iterator<T>::operator*() {
return current->data;
}
template <class T>
Node_iterator<T> Node_iterator<T>::operator++(int) {
Node<T>* temp = current;
current = current->next;
return *this;
}
template <class T>
Node_iterator<T>::Node_iterator() {
current = nullptr;
}
template <class T>
Node_iterator<T>::Node_iterator(Node<T> *n) {
current = n;
}
template <class T>
Node_iterator<T> Node_iterator<T>::operator--(int) {
Node<T>* temp = current;
current = current->prev;
return *this;
}
template <class T>
bool Node_iterator<T>::operator!=(const Node_iterator<T> *n) const{
return current != n->current;
}
template <class T>
Node_iterator<T>& Node_iterator<T>::operator++() {
current = current->next;
return *this;
}
template <class T>
Node_iterator<T>& Node_iterator<T>::operator--() {
current = current ->prev;
return *this;
}
template <class T>
bool Node_iterator<T>::operator==(const Node_iterator<T> *n) const {
return current == n->current;
}
#endif
main.cpp:
#include <iostream>
#include "LinkedList.h"
using namespace std;
int main() {
LinkedList<int> list;
list.push_back(2);
list.push_front(3);
list.insertAfter(2,5);
list.insertBefore(3,6);
LinkedList<int>::iterator iter;
for (iter = list.begin(); iter != list.end(); ++iter)
{
cout <<*iter<<endl;
}
cout << list;
}
This is the error shown in the terminal, it's a big lengthy, that's why I didn't want to post it:
C:\Users\baoto\CLionProjects\LinkedList_Template\main.cpp: In function 'int main()':
C:\Users\baoto\CLionProjects\LinkedList_Template\main.cpp:11:36: error: no match for 'operator!=' (operand types are 'LinkedList<int>::iterator {aka Node_iterator<int>}' and 'LinkedList<int>::iterator {aka Node_iterator<int>}')
for (iter = list.begin(); iter != list.end(); ++iter)
~~~~~^~~~~~~~~~~~~
In file included from C:\Users\baoto\CLionProjects\LinkedList_Template\Node_iterator.h:26:0,
from C:\Users\baoto\CLionProjects\LinkedList_Template\LinkedList.h:8,
from C:\Users\baoto\CLionProjects\LinkedList_Template\main.cpp:2:
C:\Users\baoto\CLionProjects\LinkedList_Template\Node_iterator.cpp:32:6: note: candidate: bool Node_iterator<T>::operator!=(const Node_iterator<T>*) const [with T = int]
bool Node_iterator<T>::operator!=(const Node_iterator<T> *n) const{
^~~~~~~~~~~~~~~~
C:\Users\baoto\CLionProjects\LinkedList_Template\Node_iterator.cpp:32:6: note: no known conversion for argument 1 from 'LinkedList<int>::iterator {aka Node_iterator<int>}' to 'const Node_iterator<int>*'
In file included from C:/mingw32/lib/gcc/i686-w64-mingw32/7.3.0/include/c++/iosfwd:40:0,
from C:/mingw32/lib/gcc/i686-w64-mingw32/7.3.0/include/c++/ios:38,
from C:/mingw32/lib/gcc/i686-w64-mingw32/7.3.0/include/c++/ostream:38,
from C:/mingw32/lib/gcc/i686-w64-mingw32/7.3.0/include/c++/iostream:39,
from C:\Users\baoto\CLionProjects\LinkedList_Template\main.cpp:1:
C:/mingw32/lib/gcc/i686-w64-mingw32/7.3.0/include/c++/bits/postypes.h:221:5: note: candidate: template<class _StateT> bool std::operator!=(const std::fpos<_StateT>&, const std::fpos<_StateT>&)
operator!=(const fpos<_StateT>& __lhs, const fpos<_StateT>& __rhs)
^~~~~~~~
C:/mingw32/lib/gcc/i686-w64-mingw32/7.3.0/include/c++/bits/postypes.h:221:5: note: template argument deduction/substitution failed:
C:\Users\baoto\CLionProjects\LinkedList_Template\main.cpp:11:48: note: 'LinkedList<int>::iterator {aka Node_iterator<int>}' is not derived from 'const std::fpos<_StateT>'
for (iter = list.begin(); iter != list.end(); ++iter)
^
In file included from C:/mingw32/lib/gcc/i686-w64-mingw32/7.3.0/include/c++/bits/stl_algobase.h:64:0,
from C:/mingw32/lib/gcc/i686-w64-mingw32/7.3.0/include/c++/bits/char_traits.h:39,
from C:/mingw32/lib/gcc/i686-w64-mingw32/7.3.0/include/c++/ios:40,
from C:/mingw32/lib/gcc/i686-w64-mingw32/7.3.0/include/c++/ostream:38,
from C:/mingw32/lib/gcc/i686-w64-mingw32/7.3.0/include/c++/iostream:39,
from C:\Users\baoto\CLionProjects\LinkedList_Template\main.cpp:1:
C:/mingw32/lib/gcc/i686-w64-mingw32/7.3.0/include/c++/bits/stl_pair.h:456:5: note: candidate: template<class _T1, class _T2> constexpr bool std::operator!=(const std::pair<_T1, _T2>&, const std::pair<_T1, _T2>&)
operator!=(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y)
^~~~~~~~
C:/mingw32/lib/gcc/i686-w64-mingw32/7.3.0/include/c++/bits/stl_pair.h:456:5: note: template argument deduction/substitution failed:
C:\Users\baoto\CLionProjects\LinkedList_Template\main.cpp:11:48: note: 'LinkedList<int>::iterator {aka Node_iterator<int>}' is not derived from 'const std::pair<_T1, _T2>'
for (iter = list.begin(); iter != list.end(); ++iter)
^
In file included from C:/mingw32/lib/gcc/i686-w64-mingw32/7.3.0/include/c++/bits/stl_algobase.h:67:0,
from C:/mingw32/lib/gcc/i686-w64-mingw32/7.3.0/include/c++/bits/char_traits.h:39,
from C:/mingw32/lib/gcc/i686-w64-mingw32/7.3.0/include/c++/ios:40,
from C:/mingw32/lib/gcc/i686-w64-mingw32/7.3.0/include/c++/ostream:38,
from C:/mingw32/lib/gcc/i686-w64-mingw32/7.3.0/include/c++/iostream:39,
from C:\Users\baoto\CLionProjects\LinkedList_Template\main.cpp:1:
C:/mingw32/lib/gcc/i686-w64-mingw32/7.3.0/include/c++/bits/stl_iterator.h:311:5: note: candidate: template<class _Iterator> bool std::operator!=(const std::reverse_iterator<_Iterator>&, const std::reverse_iterator<_Iterator>&)
operator!=(const reverse_iterator<_Iterator>& __x,
^~~~~~~~
C:/mingw32/lib/gcc/i686-w64-mingw32/7.3.0/include/c++/bits/stl_iterator.h:311:5: note: template argument deduction/substitution failed:
C:\Users\baoto\CLionProjects\LinkedList_Template\main.cpp:11:48: note: 'LinkedList<int>::iterator {aka Node_iterator<int>}' is not derived from 'const std::reverse_iterator<_Iterator>'
for (iter = list.begin(); iter != list.end(); ++iter)
^
In file included from C:/mingw32/lib/gcc/i686-w64-mingw32/7.3.0/include/c++/bits/stl_algobase.h:67:0,
from C:/mingw32/lib/gcc/i686-w64-mingw32/7.3.0/include/c++/bits/char_traits.h:39,
from C:/mingw32/lib/gcc/i686-w64-mingw32/7.3.0/include/c++/ios:40,
from C:/mingw32/lib/gcc/i686-w64-mingw32/7.3.0/include/c++/ostream:38,
from C:/mingw32/lib/gcc/i686-w64-mingw32/7.3.0/include/c++/iostream:39,
from C:\Users\baoto\CLionProjects\LinkedList_Template\main.cpp:1:
C:/mingw32/lib/gcc/i686-w64-mingw32/7.3.0/include/c++/bits/stl_iterator.h:349:5: note: candidate: template<class _IteratorL, class _IteratorR> bool std::operator!=(const std::reverse_iterator<_Iterator>&, const std::reverse_iterator<_IteratorR>&)
operator!=(const reverse_iterator<_IteratorL>& __x,
^~~~~~~~
C:/mingw32/lib/gcc/i686-w64-mingw32/7.3.0/include/c++/bits/stl_iterator.h:349:5: note: template argument deduction/substitution failed:
C:\Users\baoto\CLionProjects\LinkedList_Template\main.cpp:11:48: note: 'LinkedList<int>::iterator {aka Node_iterator<int>}' is not derived from 'const std::reverse_iterator<_Iterator>'
for (iter = list.begin(); iter != list.end(); ++iter)
^
In file included from C:/mingw32/lib/gcc/i686-w64-mingw32/7.3.0/include/c++/bits/stl_algobase.h:67:0,
from C:/mingw32/lib/gcc/i686-w64-mingw32/7.3.0/include/c++/bits/char_traits.h:39,
from C:/mingw32/lib/gcc/i686-w64-mingw32/7.3.0/include/c++/ios:40,
from C:/mingw32/lib/gcc/i686-w64-mingw32/7.3.0/include/c++/ostream:38,
from C:/mingw32/lib/gcc/i686-w64-mingw32/7.3.0/include/c++/iostream:39,
from C:\Users\baoto\CLionProjects\LinkedList_Template\main.cpp:1:
C:/mingw32/lib/gcc/i686-w64-mingw32/7.3.0/include/c++/bits/stl_iterator.h:1130:5: note: candidate: template<class _IteratorL, class _IteratorR> bool std::operator!=(const std::move_iterator<_IteratorL>&, const std::move_iterator<_IteratorR>&)
operator!=(const move_iterator<_IteratorL>& __x,
^~~~~~~~
C:/mingw32/lib/gcc/i686-w64-mingw32/7.3.0/include/c++/bits/stl_iterator.h:1130:5: note: template argument deduction/substitution failed:
C:\Users\baoto\CLionProjects\LinkedList_Template\main.cpp:11:48: note: 'LinkedList<int>::iterator {aka Node_iterator<int>}' is not derived from 'const std::move_iterator<_IteratorL>'
for (iter = list.begin(); iter != list.end(); ++iter)
^
In file included from C:/mingw32/lib/gcc/i686-w64-mingw32/7.3.0/include/c++/bits/stl_algobase.h:67:0,
from C:/mingw32/lib/gcc/i686-w64-mingw32/7.3.0/include/c++/bits/char_traits.h:39,
from C:/mingw32/lib/gcc/i686-w64-mingw32/7.3.0/include/c++/ios:40,
from C:/mingw32/lib/gcc/i686-w64-mingw32/7.3.0/include/c++/ostream:38,
from C:/mingw32/lib/gcc/i686-w64-mingw32/7.3.0/include/c++/iostream:39,
from C:\Users\baoto\CLionProjects\LinkedList_Template\main.cpp:1:
C:/mingw32/lib/gcc/i686-w64-mingw32/7.3.0/include/c++/bits/stl_iterator.h:1136:5: note: candidate: template<class _Iterator> bool std::operator!=(const std::move_iterator<_IteratorL>&, const std::move_iterator<_IteratorL>&)
operator!=(const move_iterator<_Iterator>& __x,
^~~~~~~~
C:/mingw32/lib/gcc/i686-w64-mingw32/7.3.0/include/c++/bits/stl_iterator.h:1136:5: note: template argument deduction/substitution failed:
C:\Users\baoto\CLionProjects\LinkedList_Template\main.cpp:11:48: note: 'LinkedList<int>::iterator {aka Node_iterator<int>}' is not derived from 'const std::move_iterator<_IteratorL>'
for (iter = list.begin(); iter != list.end(); ++iter)
^
In file included from C:/mingw32/lib/gcc/i686-w64-mingw32/7.3.0/include/c++/string:41:0,
from C:/mingw32/lib/gcc/i686-w64-mingw32/7.3.0/include/c++/bits/locale_classes.h:40,
from C:/mingw32/lib/gcc/i686-w64-mingw32/7.3.0/include/c++/bits/ios_base.h:41,
from C:/mingw32/lib/gcc/i686-w64-mingw32/7.3.0/include/c++/ios:42,
from C:/mingw32/lib/gcc/i686-w64-mingw32/7.3.0/include/c++/ostream:38,
from C:/mingw32/lib/gcc/i686-w64-mingw32/7.3.0/include/c++/iostream:39,
from C:\Users\baoto\CLionProjects\LinkedList_Template\main.cpp:1:
C:/mingw32/lib/gcc/i686-w64-mingw32/7.3.0/include/c++/bits/allocator.h:158:5: note: candidate: template<class _T1, class _T2> bool std::operator!=(const std::allocator<_CharT>&, const std::allocator<_T2>&)
operator!=(const allocator<_T1>&, const allocator<_T2>&)
^~~~~~~~