Qt - 以自定义 class 作为键的 QMap
Qt - QMap with custom class as key
我有一个以自定义 class 作为键的 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<
的定义有误。如果条件为假,则实际上 short-circuits 在第一个条件下,第二个条件无关紧要。
对此要非常小心,为容器提供错误的实现被认为是 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;
}
我有一个以自定义 class 作为键的 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<
的定义有误。如果条件为假,则实际上 short-circuits 在第一个条件下,第二个条件无关紧要。
对此要非常小心,为容器提供错误的实现被认为是 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;
}