Каковы возможные способы сделать пользовательский тип возможным ключом для карты

Недавно мне задали вопрос, как сделать настраиваемый тип возможным ключом для stl :: map.

Сразу же я ответил им, что нужно перегрузить операторную функцию «‹ », чтобы поддерживать настраиваемый тип. Вот ссылка "ссылка настраиваемого типа "

Когда меня спросили, как еще можно решить эту проблему. Я только намекнул, что мы можем сделать это, также перегрузив оператор "==". Но ответ его не удовлетворил.

Пожалуйста, помогите мне узнать, есть ли другие способы решения этой проблемы «сделать пользовательский тип в качестве возможного ключа для карты».


person Community    schedule 11.02.2014    source источник


Ответы (2)


std::maps требуют сравнения типов ключей меньше (или эквивалентного; less<key_type> - значение по умолчанию для таблицы 102).

[C++11: 23.2.4/3]: Фраза «эквивалентность ключей» означает отношение эквивалентности, налагаемое сравнением, а не operator== для ключей. То есть два ключа k1 и k2 считаются эквивалентными, если для объекта сравнения comp, comp(k1, k2) == false && comp(k2, k1) == false. Для любых двух ключей k1 и k2 в одном контейнере вызов comp(k1, k2) всегда должен возвращать одно и то же значение.

Таким образом, вы можете предоставить функцию компаратора, отличную от less<key_type>, чтобы избежать вызова operator<, но конечный результат, как определено выше, должен быть таким же. operator== совершенно не имеет значения.

#include <iostream>
#include <map>

/**
 * A comparator that defines strict-weak ordering,
 * but is backwards!
 */
struct Comp
{
   bool operator()(const int& lhs, const int& rhs)
   { return rhs < lhs; }
};

int main()
{
   {
      std::map<int, char> m;        // uses default less<int> comparator
      m[0] = 'a';
      m[1] = 'b';
      m[2] = 'c';

      for (auto el : m)
         std::cout << el.second;    // "abc"
   }
   {
      std::map<int, char, Comp> m;  // uses my own comparator defined above
      m[0] = 'a';
      m[1] = 'b';
      m[2] = 'c';

      for (auto el : m)
         std::cout << el.second;    // "cba"  ... which is true ;)
   }
}

Живая демонстрация

person Lightness Races in Orbit    schedule 11.02.2014

Здесь std :: maps с определяемыми пользователем типами в качестве ключа у вас есть способ специализации std :: map с функцией компаратора для вашего пользовательского класса.

Вероятно, интервьюер был недоволен, потому что == не может предоставить метод времени журнала (N) для доступа к значениям карты. Фактически, вы должны проверить весь набор ключей на наличие одинаковых ключей, если вам предоставлено только равенство. Карта не может работать только с равенством.

person jimifiki    schedule 11.02.2014
comment
std::map никогда не будет использовать ==. - person James Kanze; 11.02.2014
comment
Вероятно, интервьюер был недоволен неправильным ответом. - person Lightness Races in Orbit; 11.02.2014