В начале этого обсуждения я упоминал, что элементы в map хранятся в отсортированном по ключам порядке, так что при переборе от begin до end каждый элемент будет «больше», чем предшествующий (а в multimap — больше или равен ему) Но при использовании более сложных ключей, чем string или числа, может потребоваться указать, как при вставке элементов в отображение следует сравнивать ключи.

По умолчанию ключи хранятся с помощью стандартного функтора less (объявленного в ). less — это двоичная функция (принимает два аргумента одинакового типа), которая возвращает bool, указывающий на то, больше ли первый аргумент, чем второй, или нет. Другими словами, less(a, b) возвращает a < b. Если это не то, что вам требуется, создайте свой собственный функтор и объявите map с его помощью. Например, если в качестве ключа используется объект Person и каждый Person имеет имя и фамилию, то может потребоваться сравнивать фамилии и имена. Пример 6.7 показывает способ сделать это.

Пример 6.7. Использование собственного функтора сортировки

#include

#include

#include

using namespace std;

class Person {

 friend class PersonLessThan;

public:

 Person(const string& first, const string& last) :

  lastName_(last), firstName_(first) {}

 // ...

 string getFirstName() const {return(firstName_);}

 string getLastName() const {return(lastName_);}

private:

 string lastName_;

 string firstName_;

};

class PersonLessThan {

public:

 bool operator()(const Person& per1,

  const Person& per2) const {

  if (per1.lastName_ < per2. lastName_)      // Сравнить фамилии,

   return(true);                             // а затем

  else if (per1.lastName_ == per2.lastName_) // имена

   return(per1.firstName_ < per2.firstName_);

  else

   return(false);

 }

};

int main() {

 map personMap;

 Person per1("Billy", "Silly"),

  per2("Johnny", "Goofball"),

  per3("Frank", "Stank"),

  реr4("Albert", "Goofball");

 personMap[per1] = "cool";

 personMap[per2] = "not cool";

 personMap[per3] = "not cool";

 personMap[per4] = "cool";

 for (map::const_iterator p =

  personMap.begin(); p != personMap.end(); ++p) {

  cout << p->first.getFirstName() << " " << p->first.getLastName()

   << " is " << p->second << endl;

 }

}

map — это прекрасный способ хранить пары ключ/значение. После того как вы поймете поведение его частей, таких как operator[] и хранение данных (в виде объектов pair), map предоставит простоту в использовании и высокую производительность.

Смотри также

Рецепт 6.7.

<p>6.7. Использование хеш-контейнеров</p>Проблема

Требуется сохранить ключи и значения, обеспечив постоянное время доступа к элементам, и не требуется хранения элементов в упорядоченном виде.

Решение

Используйте один из связанных с хешами контейнеров — hash_map или hash_set. Однако помните, что они не входят в число стандартных контейнеров, определяемых стандартом С++, а представляют собой расширения, включаемые большинством реализаций стандартной библиотеки. Пример 6.8 показывает, как использовать hash_set.

Пример 6.8. Хранение строк в hash_set

#include

#include

#include

int main() {

 hash_set hsString;

 string s = "bravo";

 hsString.insert(s);

 s = "alpha";

 hsString.insert(s);

 s = "charlie";

 hsString.insert(s);

 for (hash set::const_iterator p = hsString.begin();

  p != hsString.end(); ++p)

  cout << *p << endl; // заметьте, что здесь не гарантируется хранение

                      // в упорядоченном виде

}

Обсуждение
Перейти на страницу:

Похожие книги