|
Программирование >> Операторы преобразования типа
и должно быть! Такое поведение следует из того факта, что интервалы являются полуоткрытыми. Чтобы задать все элементы контейнера, необходимо установить второй итератор в позицию за последним элементом. Для обратного итератора эта позиция соответствует позиции перед первым элементом. Но, к сожалению, такая позиция может оказаться несуществующей. Контейнер не обязан гарантировать, что позиция перед его первым элементом является действительной. Кроме того, обычные строки и масс1шы тоже могут быть контейнерами, а язык не гарантирует, что адресация массива не начинается с нуля. В итоге проектировщики обратных итераторов пошли на уловку: оии физически обратили концепцию полуоткрытого интервала. Интервал, определяемый обратными итераторами, включает начало, но не в]слючает конец. Тем не менее на логпческо.м уровне обратные итераторы ведут себя, как обычные. Следовательно, суп(ествуст различие между ([пзической позицис1т, определяющей элемент, па который ссылается итератор, и логической позицией, определяющей зиаченис, на которое ссылается итератор (рис. 7.3). Спра1ливастся, что должно происходить при преобразовании обычного итератора в обратный? Должен ли итератор сохранить свою логическую позицию (значение) или физическую позицию (элемент)? Как видно из предыдущего примера, выполняется второе условие, то есть логическая позиция смещается к предыдущему элементу (рис. 7.4). rend() rbeginO Значение >3нвчение Рис. 7.3. Позиция и значение обратного итератора Рис. 7.4. Преобразование обычного итератора pos в обратный итератор rpos Вам непонятен смысл такого решения? У него есть свои достоинства: например, вам ничего не придется делать при преобразовании интервала, заданного двумя итераторами. Все элементы остаются действительными. Рассмотрим следующий пример: 1tGr/reviter3.cpp #1nclude <lostrGam> #lnclude <deque> #1nclude <algor1thni> using namespace std; void print (mt elem) { cout el em : lnt malnO { dequG<int> coll; Вставка зпементов со значениями от 1 до 9 for (lnt 1=1: 1<=9: ++1) { coll ,push bacl<(1): Поиск позиции элемента со значением 2 deque<int>::iterator posl; posl = find (coll.beginO. coll.endO. Интервал 2): Значение Поиск позиции элемента со значением 7 deque<int>::iterator pos2: pos2 = find (coll.beginO. coll.endO. Интервал 7); Значение Вывод всех элементов в интервале [posl.pos2) for each (posl. pos2. Интервал print): Операция cout endl: Преобразование итераторов в обратные итераторы deque<int>: :reverse 1 terator rposKposl): deque<lnt>::reverse 1terator rpos2(pos2); Вывод всех элементов интервала [posl.pos2) в обратном порядке for each (rpos2. rposl. Интервал print): Операция cout endl: Итераторы posl и pos2 определяют полуоткрытый интервал, в который входит элемент со значением 2, но не входит элемент со значением 7. Когда итера- торы, определяющие этот интервал, преобразуются d обратные итераторы, интервал остается действительным и может быть обработан в обратном порядке. Результат выполнения программы выглядит так; 2 3 4 5 6 6 5 4 3 2 Итак; О rbeginO - это просто: контейнер ::reverse iterator(endC)) О rend() - это просто; контейнер::reverse iterator(beglnC)) Конечно, константные итераторы преобразуются к типу const reversejterator. Преобразование обратных итераторов в обычные функцией base Обратный итератор можно снова преобразовать в обычный. Для этой цели обратные итераторы поддерживают функцию base(): namespace std { template <class Iterator> class reversejterator ... { Iterator baseO const; Пример использования base(): 1ter/reviter4.cpp #include <iostream> #include <l1st> #1nclude <algor1thm> using namespace std; 1nt ma1n() { I1st<1nt> coll; Вставка элементов со значениями от 1 до 9 for (int 1-1: 1< 9; ++1) { coll.push back(i); Поиск позиции эпенента со значением 5 I1st<1nt>::1terator pos; pos = find (coll .beginO. coll.endO. Интервал 5): Значение
|
© 2006 - 2025 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки. |