При переходе от map/multimap к контейнеру vector ситуация становится более интересной, поскольку vector должен содержать объекты pair, входящие в map/ multimap. Но при объявлении объекта типа map
(или его multimap-аналога) элементы, хранящиеся в контейнере, в действительности относятся к типу pair
. Чтобы эмулировать map или multimap на базе vector, признак константности необходимо устранить, поскольку в процессе сортировки элементы вектора перемещаются посредством присваивания, а это означает, что оба компонента пары должны допускать присваивание. Следовательно, при эмуляции map
на базе vector данные, хранящиеся в векторе, должны относиться к типу pair
, а не pair
.
Содержимое map/multimap хранится в отсортированном виде, но при сортировке учитывается только ключевая составляющая элемента (первый компонент пары), поэтому при сортировке vector должно происходить то же самое. Нам придется написать собственную функцию сравнения для пар, поскольку оператор < типа pair сравнивает
Интересно заметить, что для выполнения поиска требуется вторая функция сравнения. Функция сравнения, используемая при сортировке, получает два объекта pair, но поиск выполняется только по значению ключа. С другой стороны, функция сравнения, используемая при поиске, должна получать два разнотипных объекта — объект с типом ключа (искомое значение) и pair (одна из пар, хранящихся в векторе). Но это еще не все: мы не знаем, что передается в первом аргументе — ключ или pair, поэтому в действительности для поиска необходимы две функции: одна получает ключ, а другая — объект pair. В следующем примере объединено все сказанное ранее:
typedef pair
class DataCompare{// Класс для функций сравнения public:
bool operator()(constData& Ihs, //Функция сравнения
constData& rhs) const //для сортировки
{
return keyLess(Ihs.first,rhs.first); //Определение keyLess
}//приведено ниже
bool operator()(const Data& Ihs.// Функция сравнения
const Data::first_type& k) const // для поиска (форма 1)
{
return keyLess(lhs.first,rhs.first);
bool operator()(const Data::first_type& k.// Функция сравнения
const Data& rhs) const;// для поиска (форма 2)
{
return keyLess(k.rhs.first);
}
private:// "Настоящая" функция
bool keyLess(const Data::first_type& kl.// сравнения
const Data::first_type& k2) const
{
return kl < k2;
}
}
В данном примере предполагается, что сортированный вектор эмулирует map
Контейнер map эмулируется на базе сортированного вектора практически так же, как и контейнер set. Единственное принципиальное отличие заключается в том, что в качестве функций сравнения используются объекты DataCompare:
vector
// Подготовительная фаза: много вставок, // мало операций поиска
sort(vd.begin().vd.end(),DataCompare()); // Конец подготовительной фазы