PDA

View Full Version : QHashIterator doesn't work as expected (while QHash::const_iterator does)



melon
5th August 2010, 22:55
Hello everyone,

First: great forum, a lot of useful information. Thanks for all experienced users for support.

I have some issues while trying to iterate through QHash data structure designed as:

QHash<QString, QHash<QString, int> >

A brief description of a class:


class RCDelayedRpcCaller : public QObject
{
Q_OBJECT
public:
explicit RCDelayedRpcCaller(renderclient::RenderClient *rc, QObject *parent = 0);
(...)
private:
// el.name, el.attr, value
// | | |
QHash<QString, QHash<QString, int> > scalarHashTable;
(...)
//object that gets data from above data structure
renderclient::RenderClient *renderClient;
(...)
};


When I'm trying to implement that with QHashIterator, the program crashes:


QHashIterator<QString, QHash<QString, int> > i(scalarHashTable);
while (i.hasNext()){
qDebug() << i.key();// crashes here;
QHash<QString, int> attribute = i.value();
QHashIterator<QString, int> j(attribute);
while (j.hasNext()){
renderClient->set_scalar_type_attribute(i.key(), j.key(), j.value());
}
}

In debuger it shows hashTable structures and it seems to be just fine. I've found that changing from iterator to following code works and does what's expected:


QHash<QString, QHash<QString, int> >::const_iterator i = scalarHashTable.constBegin();
while (i != scalarHashTable.constEnd()){
QHash<QString, int>::const_iterator j = i.value().constBegin();
while (j != i.value().constEnd()){
renderClient->set_scalar_type_attribute(i.key(), j.key(), j.value());
++j;
}
++i;
}


What am I doing wrong? I'd like to use QHashIterator, as it looks better for my eyes:) but can't get it working.

ChrisW67
6th August 2010, 02:02
The value is not available until you call next() on the Java-style iterator (http://doc.trolltech.com/4.6/containers.html#java-style-iterators):


QHashIterator<QString, QHash<QString, int> > i(scalarHashTable);
while (i.hasNext()){
(void) i.next(); // <<<<<< you have to step the Java-style iterator to get the value
qDebug() << i.key();
QHash<QString, int> attribute = i.value();
QHashIterator<QString, int> j(attribute);
while (j.hasNext()){
(void) j.next(); // <<<<<< you have to step the Java-style iterator to get the value
renderClient->set_scalar_type_attribute(i.key(), j.key(), j.value());
}
}

I am discarding the next() return value, you might want to capture it.

melon
6th August 2010, 09:10
Works as expected, thank you! :)

I assumed that hasNext() do the job, but that is just another "read the docs, Luke" case :)