qtqmap

Qt - QMap with custom class as key


I have a QMap with a custom class as key but when I try to insert elements with different keys, sometimes the map replace another element. In my case the problem is this:

#include <QCoreApplication>
#include <QMap>
#include <QDebug>

class A
{
  public:
    A(int value, const QString& string) { m_value = value; m_string = string; }

    bool operator<(const A& other) const { return m_value < other.m_value && m_string < other.m_string; }

  private:
    int m_value;
    QString m_string;
};

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

  QMap<A, QString> map;

  map.insert(A(10, "ONE"), "FIRST");
  map.insert(A(10, "TWO"), "SECOND");
  map.insert(A(20, "THREE"), "THIRD");

  return 0;
}

If you run this code, you will note that "FIRST" element and "SECOND" are mixed up. The map result like that:

enter image description here

Am i doing something wrong?


Solution

  • There is an error in your definition of the operator<. It actually short-circuits at the first condition if the condition is false and the second condition just doesn't matter. Be very careful with this, it is considered UB to provide wrong realization to a container.

    But in your case there is a problem only with the keys. According to your code A(10, "ONE") and A(10, "TWO") are the same key. So everything works the following way:

    map.insert(A(10, "ONE"), "FIRST");    // insert first element
    map.insert(A(10, "TWO"), "SECOND");   // put value `SECOND` in the found key
    map.insert(A(20, "THREE"), "THIRD");  // put second element
    

    And you've got a mixed up keys in the map of a wrong size.

    Try this:

    bool operator<(const A& other) const {
        if (m_value < other.m_value) return true;
        return m_string < other.m_string;
    }