问题描述
我有一个带有自定义类作为键的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”是混合在一起的。 地图结果如下:
我做错什么了吗?
解决方法
您对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;
}