当使用std :: map我应该重载operator ==的密钥类型?

时间:2013-11-23 21:34:37

标签: c++ stl

std :: map不应该有重复的密钥,所以当我有自定义类型时它如何知道我有一个重复的密钥,我是否需要做重载重载运算符==?或者它将被隐式创建?

根据文件我只需要操作员<但这还不足以维持钥匙的独特性。

考虑这个例子:

class MyType{
public:
  MyType(int newId){
    id = new int;
    *id = newId;
  };
  ~MyType{
    delete id;
  }
private:
  int* id;
};

int main(){
  std::map<MyType,int> myMap;

  std::pair<std::map<MyType,int>::iterator,bool> ret;
  ret = myMap.insert ( std::pair<MyType,int>(myType(2),100) );

  if (!ret.second) {//now how can he knows that?
    std::cout << "element already existed" << endl;
  }
}

4 个答案:

答案 0 :(得分:19)

std::map并不关心密钥的文字 unicity 。它关心键等价。当ab都不为真时,键a < bb < a按定义是等效的。

另请注意,std::map不会直接使用operator <std::mapoperator <一无所知。相反,std::map使用比较谓词,其类型被指定为std::map模板的第三个参数。该参数的默认值为std::lessstd::less的实施将比较委托给operator <(除非有特殊的不同)。这就是operator <发挥作用的方式。但是,您始终可以提供自己的谓词,但不一定使用operator <

但无论如何,关键时刻是std::map使用了排序&#34; less&#34;比较而且只是&#34;较少&#34;比较。它不需要也不关心任何&#34;平等&#34;比较。

与此同时,std::unordered_map将是另一回事。它依赖于非订购&#34;平等&#34;谓词指定的比较。默认情况下为std::equal_tostd::equal_to的实施将对operator ==的调用委托给代理(除非另有说明)。

答案 1 :(得分:3)

运营商&lt;足够。可以通过测试&lt;来检查平等性。 b和b&lt;两者都返回假。

答案 2 :(得分:2)

你应该重载operator<

std::map将比较使用的密钥 !(a < b) && !(b < a)作为对唯一性的考验。

答案 3 :(得分:2)

订单关联容器仅使用严格的弱订单来标识它们的键。他们不会使用operator==()。用于定位对象的唯一比较是std::map<K, V, Compare, Allocator>的第三个模板参数。

比较用于将键分组为等价集。如果k1小于k2k1小于k2,则认为两个密钥k2k1是等效的:

bool equivalent = !(k1 < k2) && !(k2 < k1);

当然,关联容器实际上会使用更像

的东西
!predicate(k1, k2) && !predicate(k2, k1)