0

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*> getAdjacentwould 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 typenamewhen 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!

excalibur1491
  • 1,201
  • 2
  • 14
  • 29
  • 1
    possible duplicate of [Where and why do I have to put the "template" and "typename" keywords?](http://stackoverflow.com/questions/610245/where-and-why-do-i-have-to-put-the-template-and-typename-keywords) – Constructor Apr 04 '14 at 10:36
  • 1
    You have two questions in one question. Please stick with one, otherwise it falls under the "too broad" category. – László Papp Apr 04 '14 at 10:53
  • Ok, thank you. Since my secon question was a duplicate (sorry I didn't check long enough to find that), I'll stick with the first one (I'm removing the second one on the original post) – excalibur1491 Apr 04 '14 at 10:54
  • Have you taken a look at how the Qt iterators are implemented? – László Papp Apr 04 '14 at 12:53
  • I have, but that doesn't help me at all. I don't need to implement one, I just need to hide my list; if I did implement one, it would be the exact same thing as the QList one, and I still would have to have it duplicated So the only thing I need to do is to show an iterator to the user, but its actualy the iterator from the list. I just don't want to show that I have a list, but I want the user to be able to iterate through the data structure without him even knowing what data structure it is – excalibur1491 Apr 04 '14 at 13:54

0 Answers0