Можем ли мы использовать пользовательский класс для ключа в карте STL? - PullRequest
3 голосов
/ 05 августа 2010

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

Повлияет ли это на эффективность времени?

Какие еще проблемы следует применять здесь?

Ответы [ 6 ]

6 голосов
/ 05 августа 2010

Любой тип может использоваться в качестве ключа, если он

  • Копируемый
  • Назначаемый
  • Сопоставимый, так как карта сортируется по ключу

Если ваш класс представляет собой простую структуру, он уже может быть скопирован и назначен.Для того чтобы класс был сопоставим, вы должны либо внедрить operator<, либо создать карту с настраиваемой функцией сравнения для использования вместо нее.

Единственное влияние на эффективность времени дает более крупные объекты, для копирования и сравнения которых требуется больше времени.,Если объекты должны быть такого размера, тогда вы ничего не можете с этим поделать, так что не беспокойтесь об этом.

2 голосов
/ 06 августа 2010

Тип, который будет использоваться в качестве типа ключа карты, должен иметь специализацию std::less<T> или другой предикат (вместо значения по умолчанию std::less), передаваемый на карту. Реализация по умолчанию std::less использует <. Так что вы можете

  1. перегрузка operator<() для вашего типа
  2. специализировать std::less для него
  3. передать другой предикат std::map.
2 голосов
/ 05 августа 2010

Пока этот класс имеет operator< (или иным образом делает его экземпляры < -сравнимыми, например, путем определения автономного operator<, который может так или иначе принимать два таких экземпляра в качестве аргументов - или Опять же, вы делаете карту с явным объектом сравнения), она будет работать нормально. Это будет быстро, если и только если, конечно, этот оператор или функция (и другие важные биты, такие как конструктор копирования).

Редактировать : добавлен дополнительный бит, который operator< (если это то, что вы хотите использовать вместо предоставления объекта явного сравнения), не должен быть оператором, но может быть отдельной функцией - tx @Neil за указание на это в комментарии.

1 голос
/ 05 августа 2010

Что касается использования пользовательских классов для ключей, конечно.Из-за того, как определяется карта, вы должны определить оператор «меньше чем» (operator <) для вашего класса или предоставить объект сравнения при построении карты.<a href="http://www.sgi.com/tech/stl/Map.html" rel="nofollow noreferrer"> Вот пример последнего.

Что касается эффективности, не беспокойтесь преждевременно, но одна проблема заключается в том, насколько дорого делать копии ключевого объекта.

Речь идет не об эффективности, а об изменении содержания содержимого.ключи таким образом, что это повлияет на результат оператора <, пока они находятся на карте. </p>

Если вы заинтересованы в эффективной индексации с использованием различных компонентов ключа (поскольку вы говорите, что это «несколько данных»)посмотрите на boost :: multi_index .

1 голос
/ 05 августа 2010

Да, вы можете использовать любой класс в качестве ключа при условии, что он реализует оператор меньше чем <или вы предоставляете черту сравнения в определении карты. </p>

Не беспокойтесь о времени, пока оно не окажется проблемой на практике.

0 голосов
/ 30 марта 2018

Конечно, вы можете просто перегрузить оператор «<», чтобы установить пользовательский ключ. Пример: </p>

struct x
{
int t;
bool operator<(const x &a) const
{   return (this->t < a.t);      }
};

int main()
{
x p={10}, q={11}, r={12};
map<x,int> m;
m[p]=1; m[q]=2; m[r]=3;
for(auto w: m)
cout<<w.first.t<<" "<<w.second<<"\n";
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...