1

我有一个 _bstr_t 键类型的无序映射。因此,由于哈希函数默认不支持这种键类型,所以我定义了仿函数:

struct KeyHash {
    size_t operator()(const _bstr_t& key) const {
        return hash<LPCTSTR>()(key);
    }
};

接下来我定义了typedef:

typedef unordered_map<_bstr_t, RecentInfo*, KeyHash> RecentInfoMap;

并且出现了问题:如果我使用默认构造函数实例化RecentInfoMap

RecentMapInfo rim;

然后一切正常。但是,如果我想用初始桶数实例化 RecentInfoMap

RecentInfoMap rim(100);

然后地图不工作。我无法通过它的键获取值。此外,如果我在使用地图之前调用 rim.rehash(100) 也不起作用。

请解释我做错了什么。

更新:一些代码示例:

unordered_map<bstr_t, int, KeyHash> map;
_bstr_t t1("ORCL");
_bstr_t t2("ORCL");
map[t1] = 777;
map[t2] = 555;
fout << map[t1] << endl;
fout << map[t2] << endl;

一切正常:map[t1] 和 map[t2] 引用一个值 555。但是如果 map 定义为

 unordered_map<bstr_t, int, KeyHash> map(100);

然后出现错误:map 包含重复的键和 map[t1] 对 777 的引用和 map[t2] 对 555 的引用。

该语句(使用 rehash 调用)也给出了重复的键:

unordered_map<bstr_t, int, KeyHash> map;
map.rehash(100);
4

2 回答 2

2

我找到了解决方案。刚刚编写了我自己的自定义哈希函数,它可以与 char* (wchar_t*) 指针一起使用。还添加了平等函子。对我来说很好。希望它对某人有用。

struct KeyHash {
    size_t operator()(const _bstr_t& key) const {
        LPCTSTR str = key;
        LPCTSTR end = str + _tcslen(str);
        size_t hash = 2166136261U;
        while (str != end) {
            hash = 16777619U * hash ^ static_cast<size_t>(*str++);
        }
        return hash;
    }
};


struct KeyEquals {
    bool operator()(const _bstr_t& x, const _bstr_t& y) const {
        return _tcscmp(x, y) == 0;
    }
};


typedef unordered_map<_bstr_t, RecentInfo*, KeyHash, KeyEquals> RecentInfoMap;
于 2013-06-28T19:28:26.117 回答
1

您可能需要仔细检查KeyHash()(t1)KeyHash()(t2)返回。

可能是您非常(不)幸运,它在第一种情况下完全有效。虽然这有点像在黑暗中拍摄,因为我对这些 windows 数据类型了解不多。

于 2013-06-28T16:31:59.903 回答