我正在试图找出使用unordered_map
进行自定义类的一些要点。下面是我用来练习简单类Line
的代码。我很困惑为什么Line2
中main()
的{{1}}插入insert failed
的{{1}} m
和Line1
{}}都是Line2
。注意,因为我只比较3
中m
函数中的第一个值(即operator==
),因此此代码中的class Line
和Line1
应该具有相同的值键。不应该插入已存在的密钥无效吗?有人可以向我解释原因吗?谢谢!
Line2
答案 0 :(得分:6)
您的hash
和operator ==
必须满足他们当前违反的一致性要求。当根据==
两个对象相等时,根据hash
,它们的哈希码必须相等。换句话说,虽然不相等的对象可能具有相同的哈希码,但是相等的对象必须具有相同的哈希码:
size_t operator()(const Line& k) const {
return hash<float>()(k.getM());
}
由于只比较一个组件是否相等,而忽略另一个组件,因此需要更改哈希函数以使用与确定相等性相同的组件。
答案 1 :(得分:0)
你在哈希中使用了“m”和“c”的值,所以如果“m”和“c”两者都相等,那么2“Line”实例会有相同的键,但事实并非如此在你的例子中。所以,如果你这样做:
Line line1 = Line(3.0,4.0);
Line line2 = Line(3.0,4.0);
t.insert({line1, 1});
auto x = t.insert({line2, 2});
if (x.second == false)
cout << "insert failed" << endl;
你会看到它会打印“插入失败”
答案 2 :(得分:0)
您可以随时使用自定义功能来比较插入时的键:
#include <iostream>
#include <unordered_map>
class Line {
private:
float m;
float c;
public:
Line() { m = 0; c = 0; }
Line(float mInput, float cInput) { m = mInput; c = cInput; }
float getM() const { return m; }
float getC() const { return c; }
};
struct hash
{
size_t operator()(const Line& k) const
{
return ((std::hash<float>()(k.getM()) ^ (std::hash<float>()(k.getC()) << 1)) >> 1);
}
};
// custom key comparison
struct cmpKey
{
bool operator() (Line const &l1, Line const &l2) const
{
return l1.getM() == l2.getM();
}
};
int main()
{
std::unordered_map<Line, int, hash, cmpKey> mymap; // with custom key comparisom
Line line1 = Line(3.0, 4.0);
Line line2 = Line(4.0, 5.0);
Line line3 = Line(4.0, 4.0);
auto x = mymap.insert({ line1, 1 });
std::cout << std::boolalpha << "element inserted: " << x.second << std::endl;
x = mymap.insert({ line2, 2 });
std::cout << std::boolalpha << "element inserted: " << x.second << std::endl;
x = mymap.insert({ line3, 3 });
std::cout << std::boolalpha << "element inserted: " << x.second << std::endl;
return 0;
}
打印:
element inserted: true
element inserted: true
element inserted: false