std map find总是如此

时间:2016-02-12 07:24:08

标签: c++ qt stl find stdmap

我在使用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循环被调用,但第二次被跳过!我在这里缺少什么?

2 个答案:

答案 0 :(得分:4)

我猜您传递给Update方法的第一个和第二个QVariant具有不同类型的问题(例如,booluint)。 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();
    }
};