При использовании std:: map должен ли я перегрузить operator== для типа ключа?

у std::map не должно быть дублированных ключей, так как он знает, что у меня есть дублированный ключ, когда у меня есть пользовательский тип, мне нужно сделать перегрузку перегрузка operator==? Или он будет неявно создан?

согласно документации мне нужен только оператор

Рассмотрим пример:

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 ответов


std::map не заботится о буквальном уникальность ключи. Он заботится о ключах эквивалентности. Ключи!--1--> и b эквивалентны по определению, когда ни a < b, ни b < a - это правда.

обратите внимание также, что std::map напрямую не использует operator <. std::map ничего не знает о operator <. Вместо std::map использует предикат сравнения, тип которого указан в качестве третьего параметра std::map шаблон. Неисполнение значение этого параметра -std::less. Реализация std::less делегирует сравнение с operator < (если не специализировано по-разному). Вот как!--6--> вступает в игру. Но вы всегда можете предоставить тур собственный предикат, который не обязательно будет использовать operator <.

но в любом случае ключевым моментом здесь является то, что std::map использует сравнение заказа " меньше "и только сравнение" меньше". Он не нуждается и не заботится о каких-либо сравнениях "равенства".

между тем, std::unordered_map была бы другая история. Он опирается на неупорядоченное сравнение "равенства", указанное предикатом. По умолчанию это std::equal_to. Реализация std::equal_to делегирует вызов operator == (если специализировано по-разному).


оператор


вы должны перегрузить operator<.

на std::map будет сравнивать ключи с помощью !(a < b) && !(b < a) как тест на уникальность.


ассоциативные контейнеры order используют только строгий слабый порядок для идентификации ключей. Они не будут использовать operator==(). Единственное сравнение, используемое для поиска объектов, - это третий аргумент шаблона std::map<K, V, Compare, Allocator>.

сравнение используется для группировки ключей в наборы эквивалентности. Два ключа k1 и k2 считаются эквивалентными, если ни k1 меньше, чем k2, ни k2 меньше, чем k1:

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

конечно, ассоциативный контейнеры фактически будут использовать что-то вроде

!predicate(k1, k2) && !predicate(k2, k1)