插入相同的键时,自定义类的unordered_map不会导致错误

ROB*_* AI 1 c++ unordered-map

我想弄清楚使用unordered_map自定义类的一些要点.下面是我用来练习一个简单类的练习代码Line.我很困惑,为什么插入Line2in main()不会使程序输出insert failedmfor Line1和的值Line2都是3.请注意,因为我只比较第一值(即m中)operator==功能class Line,从而Line1Line2在此代码应该有相同的密钥.不应该插入已存在的密钥无效吗?有人可以向我解释原因吗?谢谢!

#include<iostream>                                                                                                                                                                                                                                                                                                                                                                                                                                          
#include<unordered_map>                                                                                                                                                                                                                    

using namespace std;                                                                                                                                                                                                                       
class Line {                                                                                                                                                                                                                               
public:                                                                                                                                                                                                                                    
  float m;                                                                                                                                                                                                                                 
  float c;                                                                                                                                                                                                                                 

  Line() {m = 0; c = 0;}                                                                                                                                                                                                                   
  Line(float mInput, float cInput) {m = mInput; c = cInput;}                                                                                                                                                                               
  float getM() const {return m;}                                                                                                                                                                                                           
  float getC() const {return c;}                                                                                                                                                                                                           
  void setM(float mInput) {m = mInput;}                                                                                                                                                                                                    
  void setC(float cInput) {c = cInput;}                                                                                                                                                                                                    

  bool operator==(const Line &anotherLine) const                                                                                                                                                                                           
    {                                                                                                                                                                                                                                      
      return (m == anotherLine.m);                                                                                                                                                                                                         
    }                                                                                                                                                                                                                                      
};                                                                                                                                                                                                                                         

namespace std                                                                                                                                                                                                                              
{                                                                                                                                                                                                                                          
  template <>                                                                                                                                                                                                                              
  struct hash<Line>                                                                                                                                                                                                                        
  {                                                                                                                                                                                                                                        
    size_t operator()(const Line& k) const                                                                                                                                                                                                 
      {                                                                                                                                                                                                                                    
        // Compute individual hash values for two data members and combine them using XOR and bit shifting                                                                                                                                 
        return ((hash<float>()(k.getM()) ^ (hash<float>()(k.getC()) << 1)) >> 1);                                                                                                                                                          
      }                                                                                                                                                                                                                                    
  };                                                                                                                                                                                                                                       
}                                                                                                                                                                                                                                          

int main()                                                                                                                                                                                                                                 
{                                                                                                                                                                                                                                          
  unordered_map<Line, int> t;                                                                                                                                                                                                              

  Line line1 = Line(3.0,4.0);                                                                                                                                                                                                              
  Line line2 = Line(3.0,5.0);                                                                                                                                                                                                              

  t.insert({line1, 1});                                                                                                                                                                                                                                                                                                                                                                                                                                      
  auto x = t.insert({line2, 2});                                                                                                                                                                                                           
  if (x.second == false)                                                                                                                                                                                                                   
    cout << "insert failed" << endl;                                                                                                                                                                                                       

  for(unordered_map<Line, int>::const_iterator it = t.begin(); it != t.end(); it++)                                                                                                                                                        
  {                                                                                                                                                                                                                                        
    Line t = it->first;                                                                                                                                                                                                                    
    cout << t.m << " " << t.c << "\n" ;                                                                                                                                                                                                    
  }                                                                                                                                                                                                                                        

  return 1;                                                                                                                                                                                                                                
}    
Run Code Online (Sandbox Code Playgroud)

das*_*ght 6

hashoperator ==必须满足他们当前违反一致性要求.当两个对象相等时==,它们的哈希码必须相等hash.换句话说,虽然不相等的对象可能具有相同的哈希代码,但是相等的对象必须具有相同的哈希代码:

size_t operator()(const Line& k) const  {
    return hash<float>()(k.getM());
}   
Run Code Online (Sandbox Code Playgroud)

由于只比较一个组件的相等性,而忽略另一个组件,因此需要更改哈希函数以使用用于确定相等性的相同组件.

  • @ROBOTAI - 如果对象以空哈希槽结尾,则不会发生冲突,因此无需比较任何内容. (2认同)