2015-04-03 70 views
2

字典定義爲如下:作爲GUID的std ::地圖鍵

typedef boost::tuple<conn_ptr, handler_ptr, rdp_ptr> conn_tuple; 
typedef std::map<GUID, conn_tuple> conn_map; 

我們得到了一個編譯錯誤:

Error 9 error C2678: binary '<' : no operator found which takes a left-hand operand of type 'const GUID' (or there is no acceptable conversion) c:\program files (x86)\microsoft visual studio 11.0\vc\include\xstddef

然後我們解決它:

struct GUIDComparer 
{ 
    bool operator()(const GUID & Left, const GUID & Right) const 
    { 
     // comparison logic goes here 
     if((Left.Data1 == Right.Data1) && (Left.Data2 == Right.Data2) && 
      (Left.Data3 == Right.Data3) && (memcmp(Left.Data4 , Right.Data4,sizeof(Right.Data4))==0) ) 
     { 
      return true; 
     } 
     return false; 
    } 
}; 
typedef boost::tuple<conn_ptr, handler_ptr, rdp_ptr> conn_tuple; 
typedef std::map<GUID, conn_tuple, GUIDComparer> conn_map; 

現在全部編譯完成,但是在運行時我們得到一個異常(無效的運算符<)。

我不知道什麼是錯的,會很高興,如果有人可以幫助

+4

另外,請注意'<'是「小於」,而不是「等於」。因此,當memcmp()返回小於零的值時返回'true'。你實現了錯誤的謂詞,這就是你得到異常的原因。 – xaizek 2015-04-03 17:26:42

+0

@feras請參閱修訂後的答案。前一個有一個重要的邏輯錯誤。 – 2015-04-03 17:55:50

回答

4

您的GUIDComparer正在比較相等性。你傳遞給地圖的函子必須產生弱排序 - 即它必須比較少或比較大,不相等。

這將工作:

struct GUIDComparer 
{ 
    bool operator()(const GUID & Left, const GUID & Right) const 
    { 
     // comparison logic goes here 
     return memcmp(&Left , &Right,sizeof(Right)) < 0; 
    } 
}; 
+0

@RichardHodges:這好多了。如果'GUID'中有填充字節,它仍然有可能被破壞。但我想象一下GUID的大多數實現不會有填充字節。 – 2015-04-03 17:56:22

+0

表示同意。我想我至少會得到解決方案在邏輯上是正確的(假設GUID是一個無襯墊的普通POD結構)。 完全安全的解決方案是根據返回-1,0或1的'compare()'函數編寫'operator <''。'''''''''''' – 2015-04-03 18:01:25

+0

不知道,是否真的有必要在代碼已經被回答時提供代碼?這教導了完全錯誤的事情。就像,你甚至不需要嘗試,只需要去讓別人爲你寫代碼。 – 2015-04-03 19:38:41

6

所顯示的比較操作可以同時爲a<bb<a返回falsea並不比爲等於b

只需將memcmp應用於整件事情並檢查結果。


附錄(由於sehe的評論)。此問題標記爲GUID類型是標準128位UUID的Windows API名稱,通用唯一標識符。它保證了POD,而且保證了連續性,因爲它保證了128位,每一個都有意義。這使得安全使用memcmp

2

您可以考慮使用Boost.UUID代替GUID它被Windows SDK提供的。

#include <boost/uuid/uuid.hpp> 

typedef std::map<boost::uuids::uuid, conn_tuple> conn_map; 

boost::uuids::uuid已經提供了必要的比較操作,這樣你就不必在其他的答案建議寫一個排序謂詞。

-1
struct GUIDComparer 
{ 
    bool operator()(const GUID & Left, const GUID & Right) const 
    {enter code here 
     // comparison logic goes here 
     return memcmp(&Left , &Right,sizeof(Right)) < 0; 
    } 
}; 

sometimes this does not work. 

it should be: return memcmp(&Left , &Right,sizeof(Right)) == -1; (not 0) 
+2

您可以添加一個解釋,你做了什麼,或者你如何修復這個功能? – depperm 2015-07-01 19:26:45

+0

這個答案在很多方面都不正確。 – o11c 2015-07-12 19:19:11