Iterator for template binary tree - c++

I write template class for binary tree:
template <class T>
class Tree {
public:
Tree():head_(NULL),size_(0){}
~Tree();
bool isEmpty()const {return size_ == 0;};
bool insert(const T& ele);
bool remove(const T& ele);
size_t size() {return size_;}
public:
class inorder_iterator
{
inorder_iterator& operator++ ();
private:
Node<T>* cur_;
};
}
What is the defintion for operator++?(I can`t compile using the following)
template <class T>
Tree<T>::inorder_iterator&
Tree<T>::inorder_iterator::operator++ ()
{
//....
}

With these changes it compiles:
template <class T>
class Node {};
template <class T>
class Tree {
Node<T> head_;
size_t size_;
public:
Tree():head_(NULL),size_(0){}
~Tree();
bool isEmpty()const {return size_ == 0;};
bool insert(const T& ele);
bool remove(const T& ele);
size_t size() {return size_;}
public:
class inorder_iterator
{
inorder_iterator& operator++ ();
private:
Node<T>* cur_;
};
};
template <class T>
typename Tree<T>::inorder_iterator&
Tree<T>::inorder_iterator::operator++ ()
{
//....
}

Related

[C++]nested class shows me "does not name a type" error while making chainiterator

trying to make chained list iterator
headerfile(20112310_3.h)
#include<iostream>
template<typename T> class Chain;
template<typename T>
class ChainNode{
friend class Chain<T>;
private:
T data;
ChainNode<T> *link;
};
template<typename T>
class Chain{
public:
Chain();
class ChainIterator{
ChainIterator(ChainNode<T> startNode=0);
T& operator*() const;
T* operator->() const;
ChainIterator& operator++();
ChainIterator operator++(int);
bool operator!=(const ChainIterator right) const;
bool operator==(const ChainIterator right) const;
private:
ChainNode<T>* current;
};
private:
ChainNode<T>* first;
};
and here's cpp file(20112310_3.cpp)
#include<iostream>
#include "20112310_3.h"
using namespace std;
template<typename T>
Chain<T>::Chain(){first=0;}
template<typename T>
Chain<T>::ChainIterator::ChainIterator(ChainNode<T> startNode){
current=startNode;
}
template<typename T>
T& Chain<T>::ChainIterator::operator*() const{
return current->data;
}
template<typename T>
T* Chain<T>::ChainIterator::operator->() const{
return &current->data;
}
template<typename T>
ChainIterator& Chain<T>::ChainIterator::operator++(){
current=current->link;
return *this;
}
template<typename T>
ChainIterator Chain<T>::ChainIterator::operator++(int){
ChainIterator old=*this;
current=current->link;
return old;
}
template<typename T>
bool Chain<T>::ChainIterator::operator!=(const ChainIterator right) const{
return current!=right.current;
}
template<typename T>
bool Chain<T>::ChainIterator::operator==(const ChainIterator right) const{
return current==right.current;
}
int main(void)
{
return 0;
}
when i try to compile this it gets error
20112310_3.cpp:26:1: error: ‘ChainIterator’ does not name a type
ChainIterator& Chain::ChainIterator::operator++(){
20112310_3.cpp:32:1: error: ‘ChainIterator’ does not name a type
ChainIterator Chain::ChainIterator::operator++(int){
how could i resolve this?
template<typename T>
ChainIterator& Chain<T>::ChainIterator::operator++() {
ChainIterator is not in scope yet when it is parsed. You have two solutions -- either qualify the full type:
template<typename T>
typename Chain<T>::ChainIterator& Chain<T>::ChainIterator::operator++() {
... or use a trailing return type, at which point ChainIterator is in scope.
template<typename T>
auto Chain<T>::ChainIterator::operator++() -> ChainIterator& {

Interface which declares functions for iteration

I have an assignment in which I need to make template classes LinkedList and Traversible. Class Traversible needs to be a interface which declares functions for indexing and iteration of some collection class. I don't exactly know how to make an interface for iterator so LinkedList can use it. I was thinking something like
template <class T, class U>
class ITraversible {
public:
virtual U begin() noexcept = 0;
virtual U end() noexcept = 0;
virtual T& operator[](int) = 0;
};
and then in LinkedList header file I would do:
template <class T>
class LinkedList : public ITraversible<T,typename LinkedList<T>::iterator> {
struct node {
T data;
node* next, *prev;
explicit node(const T&);
void connect(node*);
};
node *head, *tail;
int n;
public:
/*************************ITERATOR************************/
class iterator : public std::iterator<std::bidirectional_iterator_tag, node*> {
typename LinkedList<T>::node* itr;
explicit iterator(node*) noexcept;
friend class LinkedList;
public:
iterator& operator++();
iterator operator++(int);
iterator& operator--();
iterator operator--(int);
bool operator==(const iterator&) const noexcept;
bool operator!=(const iterator&) const noexcept;
T& operator*() const noexcept;
T& operator->() const noexcept;
};
/**********************************************************/
LinkedList() noexcept;
LinkedList(std::initializer_list<T>);
LinkedList(const LinkedList&);
LinkedList(LinkedList&&) noexcept;
~LinkedList() noexcept;
LinkedList& operator=(LinkedList) noexcept;
template <class A>
friend void swap(LinkedList<A>&, LinkedList<A>&);
void add(const T&);
void removeAt(int);
int size() const noexcept;
bool operator==(const LinkedList&) const noexcept;
bool operator!=(const LinkedList&) const noexcept;
virtual T& operator[](int) override;
virtual iterator begin() noexcept override;
virtual iterator end() noexcept override;
};
But then Traversable template has two parameters and it should have only one.
Is this what I am supposed to do? Keep in mind I am new to templates and iterators.
When creating an interface you'll need to nail down the static types of what is being returned. These may behave dynamically different but you can't change the type other than using a subtype relation when returning pointers or references.
Personally, I think this exercise is ill-advised for a C++ context. It may make some sense when using Java or C#. However, similar behavior can be obtained. A rought sketch would be something like this (although this should work it will be rather slow):
template <typename T>
struct iterator_base {
virtual iterator_base() {}
virtual iterator_base<T>* do_clone() = 0;
virtual T& do_value() = 0;
virtual void do_next() = 0;
virtual bool do_equal() = 0;
// other operations to implement operator--, operator[], ...
};
template <typename It>
class iterator: iterator_base<typename std::iterator_traits<It>::value_type> {
typedef typename std::iterator_traits<It>::value_type> type;
It it;
iterator_base<type>* do_clone() { return new iterator<It>(*this); }
type& do_value() { return *this->it; }
void do_next() { ++this->it; }
bool do_equal(iterator_base<type>* other) {
return this->it == static_cast<iterator<It>>(other)->it;
}
};
template <typename T>
class poly_iterator {
std::unique_ptr<iterator_base<T>> ptr;
public:
poly_iterator(iterator_base<T>* ptr): ptr(ptr) {}
poly_iterator(poly_iterator const& other): ptr(other.ptr->clone()) {}
poly_iterator& operator= (poly_iterator other) {
other.swap(this);
return *this;
}
void swap(poly_iterator& other) { swap(this->ptr, other.ptr); }
T& operator*() { return this->ptr->value(); }
T* operator->() { return &this->operator*(); }
poly_iterator& operator++() { this->ptr->next(); return *this; }
poly_iterator operator++(int) {
poly_iterator rc(*this);
this->operator++();
return rc;
}
bool operator== (poly_iterator const& other) {
return this->ptr->equal(other.ptr.ptr());
}
bool operator!= (poly_iterator const& other) {
return !(*this == other);
}
// other operations
};
// define a suitable specialization of std::iterator_traits<poly_iterator<T>>
template <typename T>
class ITraversible {
virtual iterator_base<T>* do_begin() = 0;
virutal iterator_base<T>* do_end() = 0;
public:
poly_iterator<T> begin() { return this->do_begin(); }
poly_iterator<T> end() { return this->do_end(); }
// other operations
};
template <typename T>
class List: public ITraversible<T> {
std::list<T> list;
iterator_base<T>* do_begin() {
return iterator<std::list<T>::iterator>(list.begin());
}
iterator_base<T>* do_end() {
return iterator<std::list<T>::iterator>(list.end());
}
public:
// whatever is needed to fill the list
};

Writing an Iterator for a Custom Class

I'll preface this by saying I am mostly working off of examples written by others, so my understanding of template classes and friend classes is subpar. I am trying to write a circular list class:
#ifndef CIRCLIST_H
#define CIRCLIST_H
#include <cstdlib>
#include <iostream>
using namespace std;
template <class T>
class Node
{
public:
Node() : next(NULL), prev(NULL) {}
Node(const T& v) : value(v), next(NULL), prev(NULL) {}
T value;
Node<T>* next;
Node<T>* prev;
};
template <class T> class circList; //Forward declaration
template <class T>
class circIterator
{
public:
circIterator() : ptr(NULL) {}
~circIterator() {}
T& operator*() { return ptr->value; }
circIterator<T> & operator=(const circIterator<T> & old) { ptr = old.ptr; return *this; }
circIterator<T> & operator++() { ptr = ptr->next; return *this; }
circIterator<T> & operator--() { ptr = ptr->prev; return *this; }
friend class circList<T>;
friend bool operator==(const circIterator<T>& l, const circIterator<T>& r) { return l.ptr == r.ptr; }
friend bool operator!=(const circIterator<T>& l, const circIterator<T>& r) { return l.ptr != r.ptr; }
private:
Node<T>* ptr;
};
template <class T>
class circList
{
//class circIterator;
public:
circList() : entry(NULL), vsize(0) {}
~circList() {}
unsigned int size() const {return size;}
typename circList<T>::template circIterator<T> add(T const& v, circIterator<T> itr);
private:
Node<T>* entry;
unsigned int vsize;
};
template <class T>
typename circList<T>::template circIterator<T> circList<T>::add(T const& v, circIterator<T> itr)
{...}
When I write a simple main.cpp which simply declares a circList, I get the error:
error: no class template named 'circIterator' in 'class circList<int>'
The error references the last line, where the add function is implemented. What exactly does this mean? Does it mean that somewhere I have to code how an circIterator should "belong" to an circList? I really have no idea.
The error is caused by the fact that in circList<T>::template you are trying to access an identifier template (which is a keyword) that is not set for the class.
Just define the function as:
template <class T>
circIterator<T> circList<T>::add(T const& v, circIterator<T> itr) {...}
and declare it as:
circIterator<T> add(T const& v, circIterator<T> itr);
And here is the working example.

Implementing an linked list [C++] compilation error

I have the following code:
template <class T>
class List {
public:
class Iterator;
class ConstIterator;
//Constructors and Destructors.
List() : head(NULL), tail(NULL), size(0) {}
List(const List& list);
~List();
//Methods
Iterator begin();
Iterator end();
void insert(const T& data);
void insert(const T& data, const Iterator& iterator);
void remove(const Iterator& iterator);
int getSize() const;
Iterator find();
void sort();
//Operators
List operator = (const List& list);
private:
class Node;
Node* head;
Node* tail;
int size;
};
template <class T>
class List<T>::Node
{
public:
//Constructors and destructors
Node(const T& _data, const Node* _next) : data(_data), next(_next) {}
~Node(); //Destructor
//Methods
//Operators
Node operator = (const Node& node);
private:
T data;
Node* next;
};
template<class T>
class List<T>::Iterator
{
public:
Iterator() : list(NULL), node(NULL){} //Constructor
Iterator(const Iterator& it) : list(it.list), node(it.node) {}
~Iterator(); //Destructor
Iterator& operator=(const Iterator& it);
T& operator * ();
T& operator ++ ();
T operator ++ (int);
T& operator -- ();
T operator -- (int);
bool operator == (const Iterator& iterator) const;
bool operator != (const Iterator& iterator) const;
private:
List<T>* list;
Node* node;
};
template<class T>
class List<T>::ConstIterator
{
public:
ConstIterator() : list(NULL), node(NULL){}
ConstIterator(const ConstIterator& it) : list(it.list), node(it.node) {}
~ConstIterator(); //Destructor
ConstIterator& operator=(const ConstIterator& it);
T& operator * ();
T& operator ++ ();
T operator ++ (int);
T& operator -- ();
T operator -- (int);
bool operator == (const ConstIterator& iterator) const;
bool operator != (const ConstIterator& iterator) const;
private:
const List<T>* list;
const Node* node;
};
template<class T>
Iterator List<T>::begin() {
return Iterator(this, head);
}
When I try to compile I get the following error:
error: expected constructor, destructor, or type conversion before ‘List’
On line:
Iterator List<T>::begin() {
I'm not sure what I'm doing wrong.
Iterator is not defined, but List<T>::Iterator is. You will also need to add typename:
template<class T>
typename List<T>::Iterator List<T>::begin() { ... };
Here, typename is required as an ambiguitator to tell the compiler that List<T>::Iterator is a type (rather than a static member). This is always required in the templated context (see here).
if you write the body of the function outside the class declaration, it should be:
typename List<T>::Iterator List<T>::begin() { ... }
edit: typename added

C++ List Implementation

So, I'm building an implementation of List for a programming exercise. So far I have this:
#include <iostream>
#include <algorithm>
using namespace std;
template <class T> class Link;
template <class T> class List_iterator;
template <class T>
class List
{
public:
typedef List_iterator<T> iterator;
List();
List(const List<T> & l);
~List();
bool empty() const;
unsigned int size() const;
T & back() const;
T & front() const;
void push_front(const T & x);
void push_back(const T & x);
void pop_front();
void pop_back();
iterator begin() const;
iterator end() const;
void insert(iterator pos, const T & x);
void erase(iterator & pos);
List<T> & operator=(const List<T> & l);
protected:
Link<T> * first_link;
Link<T> * last_link;
unsigned int my_size;
};
template <class T>
List<T>::List()
{
first_link = 0;
last_link = 0;
my_size = 0;
}
template <class T>
List<T>::List(const List & l)
{
first_link = 0;
last_link = 0;
my_size = 0;
for (Link<T> * current = l.first_link; current != 0; current = current -> next_link)
push_back(current -> value);
}
template <class T>
typename List<T>::iterator List<T>::begin() const
{
return iterator(first_link);
}
template <class T>
class Link
{
private:
Link(const T & x): value(x), next_link(0), prev_link(0) {}//pg. 204
T value;
Link<T> * next_link;
Link<T> * prev_link;
friend class List<T>;
friend class List_iterator<T>;
};
template <class T> class List_iterator
{
public:
typedef List_iterator<T> iterator;
List_iterator(Link<T> * source_link): current_link(source_link) { }
List_iterator(): current_link(0) { }
List_iterator(List_iterator<T> * source_iterator): current_link(source_iterator.current_link) { }
T & operator*(); // dereferencing operator
iterator & operator=(const iterator & rhs);
bool operator==(const iterator & rhs) const;
bool operator!=(const iterator & rhs) const;
iterator & operator++();
iterator operator++(int);
iterator & operator--();
iterator operator--(int);
protected:
Link<T> * current_link;
friend class List<T>;
};
template <class T>
T & List_iterator<T>::operator*()
{
return current_link -> value;
}
template <class T>
List_iterator<T> & List_iterator<T>::operator++()
{
current_link = current_link -> next_link;
return *this;
}
template <class T>
void List<T>::push_back(const T & x)
{
link<T> * last_link = new link<T> (x);
if (empty())
first_link = last_link;
else
{
last_link->prev_link = last_link;
last_link->prev_link = last_link;
last_link = last_link;
}
}
template <class T>
typename List<T>::iterator List<T>::end() const
{
return iterator(last_link);
}
int main()
{
List<int> l;
l.push_back(44); // list = 44
l.push_back(33); // list = 44, 33
l.push_back(11); // list = 44, 33, 11
l.push_back(22); // list = 44, 33, 11, 22
List<int> m(l);
List<int>::iterator itr(m.begin());
while (itr != m.end()) {
cout << *itr << endl;
itr++;
}
}`
I'm having a lot of trouble with my push_back() function and I'm not quite sure what's wrong. Can anyone point out my errors?
Updated Code In Progress:
#include <iostream>
#include <algorithm>
using namespace std;
template <class T> class Link;
template <class T> class List_iterator;
template <class T>
class List
{
public:
typedef List_iterator<T> iterator;
List();
List(const List<T> & l);
~List();
bool empty() const;
unsigned int size() const;
T & back() const;
T & front() const;
void push_front(const T & x);
void push_back(const T & x);
void pop_front();
void pop_back();
iterator begin() const;
iterator end() const;
void insert(iterator pos, const T & x);
void erase(iterator & pos);
List<T> & operator=(const List<T> & l);
protected:
Link<T> * first_link;
Link<T> * last_link;
unsigned int my_size;
};
template <class T>
List<T>::List()
{
first_link = 0;
last_link = 0;
my_size = 0;
}
template <class T>
List<T>::List(const List & l)
{
first_link = 0;
last_link = 0;
my_size = 0;
for (Link<T> * current = l.first_link; current != 0; current = current -> next_link)
push_back(current -> value);
}
template <class T>
typename List<T>::iterator List<T>::begin() const
{
return iterator(first_link);
}
template <class T>
class Link
{
private:
Link(const T & x): value(x), next_link(0), prev_link(0) {}//pg. 204
T value;
Link<T> * next_link;
Link<T> * prev_link;
friend class List<T>;
friend class List_iterator<T>;
};
template <class T> class List_iterator//pg.207
{
public:
typedef List_iterator<T> iterator;
List_iterator(Link<T> * source_link): current_link(source_link) { }
List_iterator(): current_link(0) { }
List_iterator(List_iterator<T> * source_iterator): current_link(source_iterator.current_link) { }
T & operator*(); // dereferencing operator
iterator & operator=(const iterator & rhs);
bool operator==(const iterator & rhs) const;
bool operator!=(const iterator & rhs) const;
iterator & operator++();
iterator operator++(int);
iterator & operator--();
iterator operator--(int);
protected:
Link<T> * current_link;
friend class List<T>;
};
template <class T>
T & List_iterator<T>::operator*()
{
return current_link -> value;
}
template <class T>
List_iterator<T> & List_iterator<T>::operator++()
{
current_link = current_link -> next_link;
return *this;
}
template <class T>
void List<T>::push_back(const T & x)
{
Link<T> * new_link = new Link<T> (x);
if (first_link = 0)
first_link = last_link = new_link;
else
{
new_link->prev_link = last_link;
last_link->next_link = new_link;
last_link = new_link;
}
my_size++;
}
template <class T>
typename List<T>::iterator List<T>::end() const
{
return iterator(last_link);
}
template <class T>
List <T>::~List()
{
Link <T> * first = first_link;
while (first != 0)
{
Link <T> * next = first->next_link;
delete first;
first = next;
}
}
template<class T>
bool List_iterator<T>::operator==(const iterator & rhs) const
{
return ( this->current_link == rhs.current_link );
}
template <class T>
bool List_iterator<T>::operator!=(const iterator & rhs) const
{
return !( *this == rhs );
}
int main()
{
List<int> l;
l.push_back(44); // list = 44
l.push_back(33); // list = 44, 33
l.push_back(11); // list = 44, 33, 11
l.push_back(22); // list = 44, 33, 11, 22
List<int> m(l);
List<int>::iterator itr(m.begin());
while (itr != m.end()) {
cout << *itr << endl;
++itr;
}
}
Mario's and Joe's answers are both valid (I would vote them up if I could).
Issue 1
Assuming that what you posted is your ACTUAL code for push_back() then Link<T> has the wrong case.
link<T> * last_link = new link<T> (x);
...should be:
Link<T> * last_link = new Link<T> (x);
Doing this gets rid of error: expected primary-expression before ‘>’ token (when compiled with g++)
Issue 2
An alternative to what Mario and Joe suggested, is to NOT hide your List<T>'s last_link. Use a temporary variable that does NOT have the same name as your class's data member. Change:
Link<T> * last_link = new Link<T> (x);
...to...
Link<T> * new_link = new Link<T> (x);
This will make your code clearer and you will be referencing the right node.
Issue 3
Following the above steps should make two logic errors in push_back() evident. I'm willing to assist, but I'm sure you will see it.
The following line creates a local variable named last_link inside push_back().
link<T> * last_link = new link<T> (x);
Referencing last_link after this will point to this local variable instead of the class member. You'll have to add this-> in front of the class ones, e.g. this->last_link = last_link;.
You have a local variable that is the same as a member variable name. When you're using last_link you're using the one that you just created in the push_back function. You're also assigning last_link->prev_link twice. Then also assigning last_link = last_link. I'd either change the name of the local variable, or add this-> in front of it.