2012-03-10 23 views
1

代碼在C++:使用struct作爲KEY和VALUE來繪製地圖。找到()操作給錯誤

#include <iostream> 
#include <map> 
#include <string> 

using namespace std; 

struct keyInfo 
{ 
    string Key1; 
    string Key2; 

    bool keyInfo::operator <(keyInfo &A) const 
    { return ((this->Key1<A.Key1)&&(this->Key2<A.Key2)); } 
}; 

struct valueInfo 
{ 
    int value1; 
    int value2; 
    int value3; 

    valueInfo(const int A,const int B,const int C) : 
    value1(A),value2(B),value3(C) {} 
}; 
typedef std::map<keyInfo, valueInfo> MapTYPE; 

int main() 
{ 
    MapTYPE TMap; 
    keyInfo K; 
    K.Key1="main"; 
    K.Key2="i"; 
    valueInfo V(-2,-3322,9000); 

    TMap.insert(MapTYPE::value_type(K,V)); 
    MapTYPE::iterator It1=TMap.find(K); 
    It1=TMap.find(K); 
    if(It1!=TMap.end()) 
    std::cout<<"Success(K): "<<It1->second.value2<<std::endl; 

    keyInfo E; 
    E.Key1="main"; 
    E.Key2="j"; 
    //TMap.insert(std::pair<keyInfo,valueInfo>(E,V)); 
    MapTYPE::iterator It2=TMap.find(E); 
    if (It2!=TMap.end()) 
    std::cout<<"Success(E): "<<(It2->second).value3<<std::endl; 

    cin.get(); 
    return 0; 
} 

當我編譯此代碼它給我的錯誤:

error C2679: binary '<' : no operator found which takes a right-hand operand of type 'const keyInfo1' (or there is no acceptable conversion)

請讓我知道我要去哪裏錯了嗎? 任何幫助是高度讚賞。 謝謝。

我試圖實現自己的運營商,在地圖<>使用,代碼如下:

#include <iostream> 
#include <map> 
#include <string> 

using namespace std; 

struct keyInfo 
{ 
    string Key1; 
    string Key2; 

    /*bool keyInfo::operator()(keyInfo const& Left,keyInfo const& Right) const{ 
     return ((Left.Key1<Right.Key1)&&(Left.Key2<Right.Key2)); 
    }*/ 
}; 

struct LessComparer{ 
    bool operator()(keyInfo const& Left,keyInfo const& Right) const{ 
     return !(Left.Key1==Right.Key1 && Left.Key2==Right.Key2); 
    } 
}; 

struct valueInfo 
{ 
    int value1; 
    int value2; 
    int value3; 

    valueInfo(const int A,const int B,const int C) : 
    value1(A),value2(B),value3(C) {} 
}; 
typedef std::map<keyInfo, valueInfo, LessComparer> MapTYPE; 

int main() 
{ 
    MapTYPE TMap; 
    keyInfo K; 
    K.Key1="main"; 
    K.Key2="i"; 
    valueInfo V(-2,-3322,9000); 

    TMap.insert(MapTYPE::value_type(K,V)); 
    MapTYPE::iterator It1=TMap.find(K); 
    It1=TMap.find(K); 
    if(It1!=TMap.end()) 
    std::cout<<"Success(K): "<<It1->second.value2<<std::endl; 

    keyInfo E; 
    E.Key1="main"; 
    E.Key2="j"; 
    //TMap.insert(std::pair<keyInfo,valueInfo>(E,V)); 
    MapTYPE::iterator It2=TMap.find(E); 
    if (It2!=TMap.end()) 
    std::cout<<"Success(E): "<<(It2->second).value3<<std::endl; 

    cin.get(); 
    return 0; 
} 

這裏我使用的是運營商()來當且僅當左,右兩個鍵1和鍵2返回0是平等的。我認爲這與map :: less的作用是一樣的,我的意思是隻有滿足條件時才返回false。

它在第一種情況下工作正常,即找到相同密鑰的TMap.find(K)。但是在第二種情況下,即TMap.find(E)通話過程中它會彈出一個錯誤說:

"Debug assertion failed" 
Expression: Invalid operator < 
+0

除了使參數'const',你也應該考慮你是否真的希望兩個鍵都小於彼此。如果'Key1'等於'A.Key1',會發生什麼? – 2012-03-10 14:20:10

回答

1

更改參數const keyInfo& A

bool keyInfo::operator <(const keyInfo &A) const // keyInfo:: is unrequired here 

std::map按住該鍵爲const T所以當std::map執行調用keyInfo.operator<()它傳遞const keyInfo&,它不能轉換爲keyInfo&

+0

仍然不能正常工作.. – 2012-03-10 14:26:00

+0

你能更具體嗎? – hmjd 2012-03-10 14:27:46

+0

我已經將參數更改爲const keyInfo&A,仍然會發生同樣的情況。 – 2012-03-10 16:08:44

6

您聲明的operator<已關閉。

struct keyInfo 
{ 
    string Key1; 
    string Key2; 

    bool keyInfo::operator <(keyInfo &A) const 
    { return ((this->Key1<A.Key1)&&(this->Key2<A.Key2)); } 
}; 

...並有以下幾個原因:

  1. 這是前綴與類內的類名稱聲明一個錯誤。如果你在課堂外定義它,你只應該這樣做。一些編譯器是寬鬆的,但標準說你不應該這樣做。
  2. 您無法編譯的原因是operator<應接受它的操作數作爲值(對於簡單的事情)或通過const&接受它的操作數。在這裏您忘記了constA
  3. 定義不正確,您的operator<的語義關閉,因爲不遵守antisymmetry的屬性。
  4. 建議將二元運算符聲明爲類之外的自由函數。

總之,正確的聲明和定義是:

struct keyInfo { 
    std::string Key1; 
    std::string Key2; 
}; 

inline bool operator<(keyInfo const& left, keyInfo const& right) { 
    if (left.Key1 < right.Key1) { return true; } 
    if (left.Key1 > right.Key1) { return false; } 
    return left.Key2 < right.Key2; 
} 

如果可以使用Boost,一個「簡單」的方式來實現,這是:

inline bool operator<(keyInfo const& left, keyInfo const& right) { 
    return boost::tie(boost::cref(left.Key1) , boost::cref(left.Key2)) 
     < boost::tie(boost::cref(right.Key1), boost::cref(right.Key2)); 
} 
+0

+1提升技巧 – Lalaland 2012-03-10 16:28:08

+0

@EthanSteinberg:謝謝,但我不記得如果'boost:cref'調用是必要的,我不記得我的頭頂。我認爲你可以在沒有'領帶'的情況下離開,但是我不想在這裏抓住任何機會。 – 2012-03-10 16:33:37

+0

我嘗試過使用自己的比較器。你可以回覆鏈接:[Using Own Comparator](http://stackoverflow.com/questions/9648100/using-own-comparator-operator-for-map-giving-error-in-case-if-key-not-發現) – 2012-03-10 16:40:14

相關問題