2016-02-12 56 views
-3

我有一個問題,使用std :: map,特別是使用find時。 我有以下代碼。std map查找總是爲真

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時,如果輸入第一個和第二個循環。到現在爲止還挺好。但第二次調用update我確實看到第一個if循環被調用,但第二個被跳過!我在這裏錯過了什麼?

+0

顯示的'運營商=='你的QVariant的,你也可以編輯一點點地做MCVE [http://www.stackoverflow.com/help/mcve]。 – dkg

+4

if(m_testMap.find(itemInfo)== m_testMap.end())的成功/失敗取決於'QVariant :: operator <'的行爲。沒有看到[最小化,完整和可驗證的示例](http://stackoverflow.com/help/mcve),很難說出可能出錯。 –

+0

所以它依賴於operator <,而不是operator ==? – Frank

回答

4

我想你傳遞給你的Update方法的第一個和第二個QVariant的問題有不同的類型(例如,booluint)。 std::map::find不使用!=運算符來比較鍵,它默認使用運算符<(更少)。如果兩個比較QVariant的值有不同的運算符類型!=和<可能矛盾。 std::map::find以下面的方式進行比較的鍵:如果容器的比較對象返回反射性假

兩個鍵被認爲是相等(即,不管在哪個元素被作爲參數傳遞的順序)。

std::map::find認爲V1等於v2的

if(!(v1<v2) && !(v2>v1)) { //is TRUE !!! 
    } 

解決你的問題,你應該定義一個std:map比較

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; 
0

更範式解決方案是使用QMap其正確實現最QVariant類型的比較。開箱即可使用userTypes(),但這仍然可能適合您的應用。

通過ВолодинАндрей提出的解決方案的清潔器版本,即建立,可能看起來像:

struct QVariantLessCompare { 
    bool operator()(const QVariant& v1,const QVariant& v2) const 
    { 
     return v1.toInt() < v2.toInt(); 
    } 
};