Итераторы могут быть проецированы на любой из трех видов карты. Бимап предоставляет три функции участника, чтобы справиться с проекцией: project_left, project_right и project_up, с итераторами проектов для left map view, right map view и сборника отношений view. Эти функции берут любой итератор из карты и извлекают итератор по проецируемому виду, указывающему на тот же элемент.
typedefbimap<std::string,multiset_of<int,std::greater<int>>>bm_type;bm_typebm;bm.insert(bm_type::value_type("John",34));bm.insert(bm_type::value_type("Peter",24));bm.insert(bm_type::value_type("Mary",12));// Find the name of the next younger person after Peterbm_type::left_const_iteratorname_iter=bm.left.find("Peter");bm_type::right_const_iteratoryears_iter=bm.project_right(name_iter);++years_iter;std::cout<<"The next younger person after Peter is "<<years_iter->second;
typedefbimap<int,std::string>bm_type;bm_typebm;bm.insert(bm_type::value_type(1,"one"));// Replace (1,"one") with (1,"1") using the right map view{bm_type::right_iteratorit=bm.right.find("one");boolsuccessful_replace=bm.right.replace_key(it,"1");assert(successful_replace);}bm.insert(bm_type::value_type(2,"two"));// Fail to replace (1,"1") with (1,"two") using the left map view{assert(bm.size()==2);bm_type::left_iteratorit=bm.left.find(1);boolsuccessful_replace=bm.left.replace_data(it,"two");assert(!successful_replace);assert(bm.size()==2);}
it все еще действует здесь, и карта осталась без изменений
замена выполняет эту замену таким образом, что:
Сложность — это постоянное время, если измененный элемент сохраняет свой первоначальный порядок по отношению ко всем представлениям; в противном случае он логарифмический.
Итератор и эталонная валидность сохраняются.
Операция полностью безопасна для исключения, т.е. карта остается неизменной, если выкинуто какое-либо исключение (созданное системой или типами данных пользователя).
заменить функции - это мощные операции, не предусмотренные стандартными контейнерами STL, и особенно удобные, когда требуется сильная защита от исключений.
Наблюдательный читатель мог заметить, что удобство замены достигается за счет: а именно, весь элемент должен быть скопирован дважды, чтобы сделать обновление (при его извлечении и внутри заменить ). Если элементы дороги для копирования, это может быть довольно вычислительной стоимостью для модификации только крошечной части объекта. Чтобы справиться с этой ситуацией, Бут. Bimap предоставляет альтернативный механизм обновления: функции modify.
Функции modify принимают функтор (или указатель на функцию) со ссылкой на данные, подлежащие изменению, тем самым устраняя необходимость в ложных копиях. Как и функции заменить , функции модифицировать сохраняют внутренние упорядочения всех индексов bimap. Однако семантика модифицируемых функций не полностью эквивалентна функциям замены. Рассмотрим, что происходит, если столкновение происходит в результате модификации элемента, то есть модифицированный элемент сталкивается с другим по отношению к некоторому уникальному представлению. В случае функций заменить , исходное значение сохраняется и способ возвращается без изменения контейнера, но функции модифицировать не могут позволить себе такой подход, поскольку модифицирующий функтор не оставляет следов предыдущего значения элемента. Таким образом, ограничения целостности приводят к следующей политике: когда происходит столкновение в процессе вызова модифицируемых функций, элемент стирается, и метод возвращается ложным. Эта разница в поведении между функциями заменить и модифицировать должна рассматриваться программистом в каждом конкретном случае.
Повышаю. Bimap определяет новые заполнители, называемые _key и _data, чтобы обеспечить более надежное решение. Вы должны включить <boost/bimap/support/lambda.hpp>, чтобы использовать их.
typedefbimap<int,std::string>bm_type;bm_typebm;bm.insert(bm_type::value_type(1,"one"));// Modify (1,"one") to (1,"1") using the right map view{bm_type::right_iteratorit=bm.right.find("one");boolsuccessful_modify=bm.right.modify_key(it,_key="1");assert(successful_modify);}bm.insert(bm_type::value_type(2,"two"));// Fail to modify (1,"1") to (1,"two") using the left map view{assert(bm.size()==2);bm_type::left_iteratorit=bm.left.find(1);boolsuccessful_modify=bm.left.modify_data(it,_data="two");assert(!successful_modify);assert(bm.size()==1);}
it больше не действует и (1,"1") удаляется из карты
Стандартные функции lower_bound и upper_bound могут использоваться для поиска всех элементов в заданном диапазоне.
Suppose we want to retrieve the elements from a bimap<int,std::string> where the left value is in the range
[20,50]
typedefbimap<int,std::string>bm_type;bm_typebm;// ...bm_type::left_iteratoriter_first=bm.left.lower_bound(20);bm_type::left_iteratoriter_second=bm.left.upper_bound(50);// range [iter_first,iter_second) contains the elements in [20,50]
Тонкие изменения в коде необходимы при рассмотрении строгих неравенств. Для извлечения элементов больше 20 и меньше 50 код должен быть переписан как
bm_type::left_iteratoriter_first=bm.left.upper_bound(20);bm_type::left_iteratoriter_second=bm.left.lower_bound(50);// range [iter_first,iter_second) contains the elements in (20,50)
Чтобы добавить к этой сложности, осторожный программист должен учитывать, что нижняя и верхняя границы интервала поиска совместимы: например, если нижняя граница 50 и верхняя граница 20, итераторы iter_first и iter_second, произведенные кодом выше, будут в обратном порядке, с возможными катастрофическими результатами, если будет испытан переход от iter_first к iter_second. Все эти детали делают поиск диапазона утомительной и подверженной ошибкам задачей.
Функция члена диапазона, часто в сочетании с лямбда-выражениями, может значительно облегчить эту ситуацию:
range_type представляет собой удобный типдеф, равный std::pair<iterator>. const_range_type также предусмотрен и равен std::pair<const_iterator,const_iterator>
_key - это рост. Ламбда-заполнитель. Для его использования необходимо включить <boost/bimap/support/lambdahpp>
range просто принимает предикаты, указывающие нижнюю и верхнюю границы искомого интервала. Пожалуйста, обратитесь к ссылке для подробного объяснения допустимых предикатов, переданных диапазону.
Одна или обе границы могут быть опущены специальным неограниченным маркером:
Статья Useful functions раздела Chapter 1. Boost.Bimap The tutorial может быть полезна для разработчиков на c++ и boost.
Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.