I am developping a Grpah class using a QList of nodes. Each node contains a QList of adjacent.
It is sure useful to be able to loop through the nodes of the graph and through the neighborhood of every node, but it seems that having a function QList<Node*> getNodes
and QList<Node*> getAdjacent
would not be very smart (because I would show that I use a QList).
So I decided to have an iterator for eah of my classes. Very simple implementation:
template<class T>
class Graph {
private:
QList< Node<T>* > _nodes;
public:
typedef typename QList< Node<T>* >::const_iterator const_iterator;
typedef typename QList< Node<T>* >::iterator iterator;
iterator begin() {return _nodes.begin();}
const_iterator begin() const {return _nodes.begin();}
const_iterator cbegin() const {return _nodes.cbegin();}
const_iterator cend() const {return _nodes.cend();}
const_iterator constBegin() const {return _nodes.constBegin();}
const_iterator constEnd() const {return _nodes.constEnd();}
iterator end() {return _nodes.end();}
const_iterator end() const {return _nodes.end();}
Graph();
/*other methods*/
};
But then I have the exact same code for my Node template class. That code works, and seems to me a good idea.
So I id something a little bit messy:
template<class T>
class Iterable {
protected:
T* _data;
public:
Iterable() {_data = new T();}
typedef typename T::const_iterator const_iterator;
typedef typename T::iterator iterator;
iterator begin() {return _data->begin();}
const_iterator begin() const {return _data->begin();}
const_iterator cbegin() const {return _data->cbegin();}
const_iterator cend() const {return _data->cend();}
const_iterator constBegin() const {return _data->constBegin();}
const_iterator constEnd() const {return _data->constEnd();}
iterator end() {return _data->end();}
const_iterator end() const {return _data->end();}
};
and then:
template<class T>
class Node : public Iterable< QList< Node<T>* > >{/*code*/};
template<class T>
class Graph : public Iterable< QList< Node<T>* > >{/*code*/};
Is this the best way to do this? Because it looks nasty, although its completely refactored...
This part is a duplicate question from. As other users pointed out in the comments, I shall stick to one question: the one above this.
*Also, now I need to type typename
when trying to get an interator type inside Graph or Node, but not outside. That is to say:
template
void Graph::example() const {
typename Graph::const_iterator it;
//If i remove typename I get: error: need ‘typename’ before ‘Graph::const_iterator’ because ‘Graph’ is a dependent scope
}
whereas outside of the class I can do:
Graph::iterator it = g.begin();
Why is this?*
Thanks!