Можно ли использовать собственный класс вместо std :: pair в карте STL? - PullRequest
2 голосов
/ 20 мая 2009

Возможно ли это?

#include <map>

class Example {

  private:
  std::map<std::string, std::string, less<std::string>,
    std::allocator< CustomPair<std::string, std::string> > > myMap;
};

В приведенном выше примере CustomPair будет классом шаблона, содержащим ключ и значение. Если это возможно, это так просто или есть что-то, на что я должен обратить внимание?

Ответы [ 4 ]

7 голосов
/ 20 мая 2009

Можно только предположить, каково ваше истинное намерение, поэтому я предполагаю, что у вас уже есть класс, который содержит и ключ, и значение. В этом случае std :: set с пользовательским сравнением может быть лучшим выбором, чем std :: map.

Затем необходимо предоставить сравнение, которое будет сравнивать только ключевую часть вашего класса, а ключевая часть должна быть константной (не изменяющейся во времени), пока объект находится в наборе. Как упомянуто в комментарии, элементы набора доступны только как conts, поэтому, если вы хотите изменить значение такого элемента, вам нужно const_cast доступ на запись или объявить изменяемый член.

В другом ответе iain сделал еще одно очень хорошее предложение. Если вы редко вставляете в контейнер и в основном обращаетесь к контейнеру в поисках элементов, тогда отсортированные std :: vector и std :: binary_search являются очень эффективной альтернативой множеству.

3 голосов
/ 20 мая 2009

Я бы либо использовал набор, как описано в lothar, либо использовал отсортированный std::vector, как описано в главе 23 «Эффективного STL»: «Рассмотрите возможность замены ассоциативных контейнеров отсортированными векторами».

Рациональным для этого является то, что std::binary_search отсортированного вектора с пользовательским компаратором почти такой же быстрый, а иногда и быстрее, чем поиск по карте, и итерация намного быстрее. Хотя операции вставки стоят дороже (вы должны вызывать сортировку после каждой вставки). Многие случаи использования карт вставляются очень редко.

Вектор будет более гибким, чем набор.

Я заменил карту из 2000 сложных объектов (индексируемых с помощью int) этим подходом, итерация и обработка каждого объекта на карте в системе классов серверов сократились с 50 секунд до менее 5. Не было заметной разницы для времени поиска по карте.

3 голосов
/ 20 мая 2009

Я бы с большей вероятностью использовал std :: set.

0 голосов
/ 20 мая 2009

Я думаю, что вы можете сделать это, но не получите желаемого эффекта, потому что использование std::allocator будет осуществляться через rebind<std::pair>, что отменяет выбор CustomPair. На самом деле, вероятно, не имеет значения, какой тип вы там поместили, функции STL его проигнорируют. По крайней мере, некоторые из них определенно сделают это, но я не уверен, что все будут. Строго говоря, это почти наверняка зависит от реализации. Я не знаю, что говорит стандарт.

...