Convert QVariantList to QList<Type> list
-
@ikim said:
How do I declare QSet<Type> at compile time when I dont know Type
You can't! In C++ you must define the type of templates.
Question: Why cannot you use
QSet<QVariant>
?? -
Hi
I need to compare two variantlist both containing variants of the same type and determine the variants that are common to both lists
Thanks
-
You can use
QVariant
directly without conversion because QVariant supportsoperator==()
-
QVariant has the == operator
-
@SGaist yes I could compare each QVariant in the list but that would mean iterating over the entire list to determine if the item exists in the second list. Is that my only option ?
Thanks
-
No, use the QSet features e.g.
QSet<QVariant> commonSet = mySet1 & mySet2;
-
@SGaist Thanks, so I can use a QSet<QVariant> out of the box ?
other forums are suggesting that I need to define a qhash() function for the QVariant.
-
QSet
is based on a hash table; this means that internally it uses qHash() -
@ikim why not use QVariant::Type method? even you can use it with c++ template.
-
@mcosta Thanks but this gives a compile error
QSet<QVariant> existingValues;
existingValues.insert(1); -
@MayEnjoy Thanks, but how would this enable me to achieve my goal ?
-
Which kind of error?
-
@mcosta /usr/include/QtCore/qhash.h:882:24: error: no matching function for call to 'qHash(const QVariant&)'
-
mmmm, You're right.
So I suggest to create a
template
methodThis code works for me
template <typename T> QSet<T> mergeList(const QVariantList& l1, const QVariantList& l2) { QSet<T> s1, s2; for (const QVariant& v: l1) { s1.insert(v.value<T>()); } for (const QVariant& v: l2) { s2.insert(v.value<T>()); } return s1 & s2; }
Used as
QVariantList l1, l2; l1 << 1 << 2 << 3; l2 << 1 << 3 << 5; QSet<int> s1 = mergeList<int> (l1, l2); qDebug() << s1; l1.clear(); l2.clear(); l1 << "Foo" << "Bar"; l2 << "Bar" << "Fred"; QSet<QString> s2 = mergeList<QString> (l1, l2); qDebug() << s2;
-
@mcosta Thanks for your effort, but this still doesn't solve the problem as I dont know the Type at compile time
-
Hi,
I'm not a C++ super-guru but I don't think you can do it because the compiler must know the type of each variable at compile time.
A solution could be implement
qHash(const QVariant &v)
and useQSet<QVariant>
-
@mcosta thanks for your time, I think you may be right :)
-
-
You can also implement qHash for the type you need to support and thus it will be used automatically in all your software.
#include <QtDebug> inline uint qHash(const QVariant &key, uint seed = 0) { switch (key.userType()) { case QVariant::Int: return qHash(key.toInt(), seed); case QVariant::UInt: return qHash(key.toUInt(), seed); // add all cases you want to support; } return 0; } int main( int argc, char * argv[] ) { QApplication app( argc, argv ); QVariantList vl1; QVariantList vl2; for (int i = 0 ; i < 5 ; ++i) { vl1 << i; } for (int i = 0 ; i < 3 ; ++i) { vl2 << i; } qDebug() << (vl1.toSet() & vl2.toSet()); return 0; }