Qt-以自定义类为键的QMap

问题描述

我有一个带有自定义类作为键的QMap,但是当我尝试插入具有不同键的元素时,有时地图会替换另一个元素。 就我而言,问题是这样的:

#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;
}

如果运行此代码,则会注意到“ FirsT”元素和“ SECOND”是混合在一起的。 地图结果如下:

enter image description here

我做错什么了吗?

解决方法

您对operator<的定义有误。如果条件为假,则实际上在第一个条件下短路,而第二个条件无关紧要。 对此要非常小心,将UB提供给容器错误的实现被认为是UB。

但是在您的情况下,仅按键存在问题。根据您的代码,A(10,"ONE")A(10,"TWO")是同一密钥。因此,一切工作都通过以下方式进行:

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

您在地图中的尺寸不正确。

尝试一下:

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