I have a linked list that contains a pointer to the first and last node and size which indicates how many nodes are there in the list.
I've implemented iterator for Queue that points to the address of the node, I've already succeeded implementing begin(),end() and ==,!=, and tested too,
but I'm unable to implement () and (int) operators for the iterators, i want the operator to change the address of the node to the next one in the linked list, i get the following error when i try to compile: no matching function for call to ‘Node<int>::getNext() const’
and how can i make the iterator operator overload to work without typing typename
at the start of the declaration
Node
class:
template<class T>
class Node {
public:
Node(const T& t);
~Node()=default; // Destructor
Node(const Node&) = default; // Copy Constructor set to default
Node& operator=(const Node&) = default; // Assignment operator set to default
T& getData();
const T& getData() const;
Node* getNext();
void setNext(Node<T>* newNext);
private:
T m_data;
Node* m_nextNode;
};
template<class T>
Node<T>::Node(const T& t) {
this->m_data=t;
this->m_nextNode=nullptr;
}
template<class T>
Node<T>* Node<T>::getNext() {
return this->m_nextNode;
}
Queue
class:
template<class T>
class Queue {
public:
static const int DEFAULT_FIRST_INDEX=0;
static const int SIZE_EMPTY=0;
Queue();
~Queue(); // Destructor
Queue(const Queue&) = default; // Copy Constructor set to default
Queue& operator=(const Queue&) = default; // Assignment operator set to default
void pushBack(const T& t);
T& front();
const T& front() const;
void popFront();
int size() const;
class Iterator;
Iterator begin() const;
Iterator end() const;
class EmptyQueue {};
private:
Node<T>* m_head;
Node<T>* m_tail;
int m_size;
};
Queue<T>::Iterator
class:
template<class T>
class Queue<T>::Iterator {
public:
const T& operator*() const;
Iterator& operator ();
Iterator operator (int);
bool operator==(const Iterator& iterator) const;
bool operator!=(const Iterator& iterator) const;
Iterator(const Iterator&)=default;
Iterator& operator=(const Iterator&)=default;
class InvalidOperation {};
private:
const Node<T>* m_node;
Iterator(const Node<T>* m_node);
friend class Queue<T>;
};
template<class T>
Queue<T>::Iterator::Iterator(const Node<T>* m_node) {
this->m_node=m_node;
}
template<class T>
typename Queue<T>::Iterator& Queue<T>::Iterator::operator () {
this->m_node=m_node->getNext();
return *this;
}
CodePudding user response:
How do I make it work without
typename
at the start of the definition?
If you meant about the function Queue<T>::Iterator::operator ()
definition, you can do it via trailing return type as follows:
template<class T>
auto Queue<T>::Iterator::operator () -> Iterator&
//^^^ ^^^^^^^^^
{
this->m_node = m_node->getNext();
return *this;
}
That been said, (IMO) moving definitions outside the same transition unit for template classes or template functions is a bit verbose and tedious.