Помимо академических мотиваций, существует практический интерес к эмуляции стандартных ассоциативных контейнеров с помощью<multi_index_container>, а именно использовать расширенные функции, предоставляемые<multi_index_container>для поиска, запроса диапазона и обновления.
Для эмуляции<std::set>можно следовать правилу замены:
В случае по умолчанию, где<Compare=std::less<Key>>и<Allocator=std::allocator<Key>>, правило замещения упрощается как
std::set<Key>->multi_index_container<Key>
Замена<multi_index_container>на<std::set>сохраняет весь набор функциональных возможностей, предоставляемых<std::set>, поэтому в принципе это замена, не требующая дальнейших корректировок.
<std::multiset>можно эмулировать аналогичным образом в соответствии со следующим правилом:
Эмуляция<std::multiset>s с<multi_index_container>приводит к незначительной разнице по отношению к предлагаемому интерфейсу: функция члена<insert(const value_type&)>возвращает<iterator>не как в<std::multiset>s, а скорее<std::pair<iterator,bool>>в духе<std::set>s. Однако в этом конкретном случае<bool>член возвращаемой пары всегда<true>.
<std::map>и<std::multimap>не поддаются такой прямой эмуляции<multi_index_container>. Основная проблема заключается в том, что элементы a<multi_index_container>рассматриваются как постоянные, в то время как<std::map>и<std::multimap>обрабатывают объекты типа<std::pair<const Key,T>>, что позволяет свободно изменять значение части. Чтобы преодолеть эту трудность, нам нужно создать специальный класс пары:
В отличие от стандартных наборов, интерфейс этих<multi_index_container>эмулированных карт не совсем соответствует интерфейсу<std::map>и<std::multimap>. Наиболее очевидным отличием является отсутствие<operator []>, либо в режиме чтения, либо в режиме записи; это, однако, можно эмулировать с соответствующим использованием<find>и<insert>.
Эти эмуляции стандартных ассоциативных контейнеров с<multi_index_container>сопоставимы с оригинальными конструкциями с точки зрения пространственной и временной эффективности. Подробнее см. вразделе.
В отличие от ассоциативных контейнеров, эмулирующих<std::list>в Boost. MultiIndex не добавляет какой-либо существенной функциональности, поэтому следующее представлено только для полноты.
Как и в случае со стандартными картами, основная трудность, которую приходится преодолевать при эмуляции<std::list>, связана с постоянной природой элементов<multi_index_container>. Опять же, необходим какой-то класс адаптации, например:
Учитывая<multi_index_container>инстанциацию, для компиляционного контроля различных типов, происходящих в определении<multi_index_container>:
< [19] >,
< [21] >,
< [23] >,
< [25] >.
Каждый из этих типов представляет собой последовательность MPL с таким количеством элементов, что индексы составляют<multi_index_container>: например,<n>- элемент<iterator_type_list>такой же, как<nth_index<n>::type::iterator>.index_specifier_type_list,
index_type_list,
iterator_type_list,
const_iterator_type_list.
Each of these types is an MPL sequence with as many elements as indices
comprise the multi_index_container: for instance, the n-th
element of iterator_type_list is the same as
nth_index<n>::type::iterator.
[ORIG_END] -->
Существует тонкое, но важное различие между<index_specifier_type_list>и<index_type_list>: В первом типологическом списке указаны указатели, с помощью которых была определена инстанциация<multi_index_container>, а в последнем доступны фактические классы реализации, соответствующие каждому спецификатору. Пример поможет прояснить это различие. Учитывая инстанциацию:
Хотя обычно индексы определяются с помощью конструкции<indexed_by>, на самом деле вместо этого может быть предоставлена любая последовательность MPL указателей индексов:
Эта возможность позволяет синтезировать инстанциации<multi_index_container>через метапрограммы MPL, как показывает следующий пример:
// original multi_index_container instantiationtypedefmulti_index_container<int,indexed_by<ordered_unique<identity<int>>>>indexed_t1;// we take its index list and add an indextypedefboost::mpl::push_front<indexed_t1::index_specifier_type_list,sequenced<>>::typeindex_list_t;// augmented multi_index_containertypedefmulti_index_container<int,index_list_t>indexed_t2;
Статья Boost.MultiIndex Documentation - Tutorial - Techniques раздела Boost.MultiIndex Documentation - Tutorial может быть полезна для разработчиков на c++ и boost.
Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.