我收到了以下test.cpp
文件
#include <string>
#include <functional>
#include <unordered_map>
#include <iostream>
class Mystuff {
public:
std::string key1;
int key2;
public:
Mystuff(std::string _key1, int _key2)
: key1(_key1)
, key2(_key2)
{}
};
namespace std {
template<>
struct hash<Mystuff *> {
size_t operator()(Mystuff * const& any) const {
size_t hashres = std::hash<std::string>()(any->key1);
hashres ^= std::hash<int>()(any->key2);
std::cout << "Hash for find/insert is [" << hashres << "]" << std::endl;
return (hashres);
}
};
}; /* eof namespace std */
typedef std::unordered_map<Mystuff *, Mystuff *>mystuff_map_t;
mystuff_map_t map;
int insert_if_not_there(Mystuff * stuff) {
std::cout << "Trying insert for " << stuff->key1 << std::endl;
if (map.find(stuff) != map.end()) {
std::cout << "It's there already..." << std::endl;
return (-1);
} else {
map[stuff] = stuff;
std::cout << "Worked..." << std::endl;
}
return (0);
}
int main(){
Mystuff first("first", 1);
Mystuff second("second", 2);
Mystuff third("third", 3);
Mystuff third_duplicate("third", 3);
insert_if_not_there(&first);
insert_if_not_there(&second);
insert_if_not_there(&third);
insert_if_not_there(&third_duplicate);
}
您可以使用g++ -o test test.cpp -std=gnu++11
进行编译。
我不知道我做错了什么:哈希键控算法肯定有效,但出于某种原因(显然是 - 糟糕的 - 我做某事) ),third_duplicate
也插入到地图中,而我希望它不是。
我做错了什么?
答案 0 :(得分:1)
IIRC无序容器需要operator==
以及std::hash
。没有它,我预计会出现编译错误。除了你的密钥实际上是MyStuff*
- 指针,而不是值。
这意味着您将重复密钥存储为单独的项目,因为它实际上不是unordered_map
的真实副本 - 它具有不同的地址,并且地址相等是{{1}的方式判断平等。
简单解决方案 - 改为使用unordered_map
。您需要重载std::unordered_map<Mystuff,Mystuff>
(或者IIRC的一些替代模板,类似于operator==
,您可以专攻)。您还需要更改std::hash
以接受值而不是指针。
不要过度使用C ++中的指针,尤其不是原始指针。对于pass-by-reference,更喜欢对指针的引用(这是指C ++特定含义&#34;引用&#34; vs.&#34;指针&#34;)。对于容器,正常的默认设置是直接使用内容类型,尽管在某些情况下您可能需要指针(或智能指针)。
我还没有彻底检查你的代码 - 可能会遇到的问题比我发现的还多。