2013-11-21 24 views
2

考慮下面的示例代碼:比較復引用地圖迭代器(標準::對):C2678

#include <map> 
#include <vector> 

int main() { 
    typedef std::pair<char, char> MyPair; 
    typedef std::multimap<char, char> MyMap; 
    typedef std::pair<MyMap::iterator, MyMap::iterator> MyRange; 

    std::vector<MyPair> pairs; 
    MyMap bigMapOfStuff; 

    //... adding things to pairs 

    auto pairsIter = pairs.begin(); 

    MyRange range = bigMapOfStuff.equal_range('a'); 

    //... range validation checking 

    MyPair pair = *range.first; 
    if(pair == *pairsIter) { //OK 
    //... 
    } 

    if(*pairsIter == *range.first) { //C2678 
    } 

    pair = *pairsIter; 
    if(*range.first == pair) { //C2678 
    //... 
    } 

    if(*range.first == *pairsIter) { //C2678 
    //... 
    } 

    if((MyPair)*range.first == *pairsIter) { //OK 
    //... 
    } 

    return 0; 
} 

在我評論// C2678的比較 - 這指的是Visual Studio 2010的錯誤:

error C2678: binary '==' : no operator found which takes a left-hand operand of type 'std::pair<_Ty1,_Ty2>' (or there is no acceptable conversion) 

爲什麼在這些情況下會發生此錯誤?

我明白pairsIterstd::vector<MyPair>::iterator,並range.firstMyMap::iterator然而,我的期望是,解引用迭代器返回的類型,在這種情況下std::pair<char, char>兩個迭代器。

爲什麼我需要明確它呢?

+0

這仍然不是完整的錯誤信息;這也包含了'_Ty1'和'_Ty2'在這個特殊情況下的含義。如果你已經讀過這個,它會暗示出這個解決方案。 – Angew

+0

@Angew啊,是的,這將教會我更經常地看看輸出窗口,當涉及到模板 – badgerr

+0

它仍然足以設置括號* pairsIter?這就像隱含的轉換,你可以直接比較它們 – Kaspatoo

回答

4

原因是std::multimap<char, char>::value_type(這也是取消引用迭代器給你的)是而不是std::pair<char, char>。這是std::pair<const char, char>。就是這樣,你不能修改存儲在地圖中的項目的關鍵,這可能會破壞地圖的不變量。

如果您分配(或CAST)提領的結果輸入std::pair<char, char>,比較有效。如果您嘗試直接比較不同的配對類型,則會出現錯誤。

您可以通過鑄造解決這個問題,或者通過提供自己的,用於比較不同類型的功能(任operator==過載或命名功能)。或者更一般地說,用於比較std:pair<T, U>std::pair<const T, U>