GUID为std::映射键

GUID as std::map key

本文关键字:映射 std GUID      更新时间:2023-10-16

字典定义如下:

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

我们得到了一个编译错误:

错误9错误C2678:二进制"<":找不到需要类型为"const GUID"的左侧操作数(或没有可接受的操作数转换)c:\program files(x86)\microsoft visual studio11.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; 

现在,所有的都已编译,但随后我们在运行时得到一个异常(无效运算符<)。

我不知道出了什么问题,如果有人能帮助,我会很高兴

您的GUIDComparer正在进行相等性比较。传递给映射的函子必须生成弱排序,即它必须比较少或比较大,而不是相等。

这将起作用:

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

a不等于b时,显示的比较运算符可以为a<bb<a返回false

只需将memcmp应用于整个事件并检查结果即可。


附录(根据sehe的意见)。此问题标记的GUID类型是标准128位UUID的Windows API名称,通用唯一标识符。它保证POD,而且保证连续,因为它保证128位,每一位都有意义。这使得使用memcmp是安全的。

您可以考虑使用Boost.UUID,而不是Windows SDK提供的GUID。

#include <boost/uuid/uuid.hpp>
typedef std::map<boost::uuids::uuid, conn_tuple> conn_map;

boost::uuids::uuid已经提供了必要的比较运算符,因此您不必像其他答案中建议的那样编写排序谓词。

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)