我在使用std :: map时遇到问题,特别是在使用find时。 我有以下代码。
class MyClass
{
update(const QVariant&);
QVariant m_itemInfo;
std::map<QVariant, int> m_testMap;
}
void update(const QVariant& itemInfo)
{
if(m_itemInfo != itemInfo)
{
// The items are not equal
m_itemInfo = itemInfo;
}
if(m_testMap.find(itemInfo) == m_testMap.end())
{
// TestMap doesnt contain key itemInfo.
m_testMap.insert(std::make_pair(itemInfo, 1));
}
// More code
}
在我的代码中多次调用函数update
(使用不同的itemInfo对象)。现在,当我开始调试它时,我看到第一次调用update
时,输入第一个和第二个if循环。到现在为止还挺好。但是第二次update
被调用时,我确实看到第一个if循环被调用,但第二次被跳过!我在这里缺少什么?
答案 0 :(得分:4)
我猜您传递给Update方法的第一个和第二个QVariant
具有不同类型的问题(例如,bool
和uint
)。 std::map::find
不使用!=运算符来比较键,它使用运算符&lt; (减去)默认情况下。如果两个比较的QVariant
值具有不同类型的运算符!=和&lt;可能会发生矛盾。
std::map::find
通过以下方式比较密钥:
如果容器的比较对象以反射方式返回false,则认为两个键是等效的(即,无论元素作为参数传递的顺序如何)。
即。 std::map::find
认为v1等于v2
if(!(v1<v2) && !(v2>v1)) { //is TRUE !!!
}
要解决您的问题,您应为std:map
定义 less 比较。
class QVariantLessCompare {
bool operator()(const QVariant& v1, QVariant& v2) const {
// ==== You SHOULD IMPLEMENT appropriate comparison here!!! ====
// Implementation will depend on type of QVariant values you use
//return v1 < v2;
}
};
以这种方式使用QVariantCompare
:
std::map<QVariant, int, QVariantLessCompare> m_testMap;
答案 1 :(得分:0)
更典型的解决方案是使用QMap
来正确实现大多数QVariant
类型的比较。它不会开箱即用userTypes()
,但这仍然适合您的应用。
ВолодинАндрей提出的解决方案的清洁版本,可能看起来像:
struct QVariantLessCompare {
bool operator()(const QVariant& v1,const QVariant& v2) const
{
return v1.toInt() < v2.toInt();
}
};