Search code examples
c++qtqvariantqmultimap

QMultiMap with QVariant as key


I have a multimap with QVariant as key, but it's not working with QByteArray.
The funcion map.values("\xc2\x39\xc7\xe1") is returning all the values of the map.
This is a small example:

#include <QCoreApplication>
#include <QMultiMap>
#include <QVariant>

int main(int argc, char *argv[])
{
  QCoreApplication a(argc, argv);

  QMultiMap<QVariant, QString> map;
  QByteArray b1("\xc1\x39\xc7\xe1");
  QByteArray b2("\xc1\x39\xc7\xe2");

  map.insert(QVariant(b1), "TEST1");
  map.insert(QVariant(b2), "TEST2");

  QStringList values = map.values(QByteArray("\xc1\x39\xc7\xe1"));

  return a.exec();
}

I tried also using a QMap to see what happens and it adds only an element to the map.
Can someone explain me this behavior?
What am I doing wrong?


Solution

  • It appears to be a bug in Qt, because the operator QVariant::operator<() does not provide a total ordering, even though QByteArray::operator<() does. And QMap relies on that (see QMap documentation).

    QByteArray b1("\xc1\x39\xc7\xe1");
    QByteArray b2("\xc1\x39\xc7\xe2");
    QVariant v1(b1);
    QVariant v2(b2);
    
    assert(b1 < b2 != b2 < b1);  // works as expected for QByteArray
    assert(v1 != v2);            // make sure the values are actually not equal
    assert(v1 < v2 != v2 < v1);  // fails for QVariant(QByteArray)
    

    So a QByteArray works as a key to a QMap, but a QVariant(QByteArray) does not.