为 unordered_set 创建了我的自定义 key_eq。但由于某种原因,他根本不使用这个函子。这是无序集合的某种特征,还是我做错了什么?
template <typename T>
class equal_for_me {
public:
bool operator() (const T & lval,const T & rval) const {
if (lval->x_ == rval->x_)
if (lval->y_ == rval->y_)
if (lval->z_ == rval->z_) {
cout << "is equal" << endl;
return 0;
}
cout << "is not equal" << endl;
return 0;
}
};
int main() {
unordered_set<shared_ptr<point>,std::hash<shared_ptr<point>>,equal_for_me<shared_ptr<point>>> data;
data.insert(std::make_shared<point>(13.0,41.0,51.0));
data.insert(std::make_shared<point>(321.0,33.0,12.0));
data.insert(std::make_shared<point>(123.0,321.0,31.0));
data.insert(std::make_shared<point>(12.0,31.0,31.0));
data.insert(std::make_shared<point>(13.0, 41.0, 51.0));// по хорошему такой элемент уже есть и не должен создаваться дубликат
for (auto i : data) {
cout << i << " : " << i->x_ << endl;
}
return 0;
}
为什么从未调用equal_for_me?
在插入
unordered_set
时,会在发生冲突时进行相等比较:两个元素被散列到同一个散列中,并因此落入同一个“桶”(bucket)中。但是您的散列函数会散列指针本身的值,而比较函数会比较指向对象的内容。这已经是某种废话了。
由于散列的是指针的值,因此所有插入的指针在
unordered_set
. 很可能它std::hash<shared_ptr<point>>
为所有这些都提供了不同的哈希值,并且它们都落入哈希表中的不同“桶”中。因此,没有必要打电话给你equal_for_me
的。一些指针point
存储相同的值这一事实并不重要。散列函子必须与比较函子相匹配。比较函子的平等必然意味着哈希的平等。您的情况不满足此要求。
相反,您
std::hash<shared_ptr<point>>
需要一个散列函子来处理point
. 你必须自己写。