|
Программирование >> Операторы преобразования типа
выглядит довольно странно, но это неизбежное следствие архитектуры STL, основанной на габком разделении контейнеров и алгоритмов. Удаление элементов Алгоритм removeO удаляет элементы из заданного интервала. Но если вызвать его для всех элементов контейнера, происходит нечто неожиданное. Пример: stl/removel.cpp #1nclude <1ostrearn> #include <list> #1nclude <algor1thm> using namespace std: Int mainC) ( l1st<int> coll: Вставка элементов со значениями от 6 до 1 и от 1 до 6 for (int 1=1; 1<=6: ++1) { coll,push front(1); coll.push back(l): Вывод всех элементов коллекции cout pre: : copy (col 1 .beginO . coll.endO. Источник ostream iterator<1nt>(cout. )); Приемник cout endl; Удаление всех элементов со значением 3 remove (coll,beginO . coll.endO, Интервал 3); Значение Вывод всех элементов коллекции cout post: ; copy (col 1-beginO , coll.endO. Источник ostream 1terator<1nt>(cout. )): Приемник cout endl: При поверхностном знакомстве с предметом напрашивается предположение, что эта программа удаляет из коллекции все элементы со значением 3. Но на самом деле результат выглядит так: pre: 654321123456 post: 654211245656 Алгоритм removeO не изменил количество элементов в коллекции, для которой он вызывался. Функция end() возвращает прежнее значение, а функция sizeQ - прежнее количество элементов. Тем не менее кое-что все же изменилось: порядок следования элементов стал таким, каким он должен стать после удаления. На место элементов со значением 3 были записаны следующие элементы (рис. 5.7). Прежние элементы в конце коллекции, не нерезахшсанные алгоритмом, остались без изменений. На логическом уровне эти элементы уже не принадлежат коллекции. игх. \У v Рис. 5.7, принцип действия алгоритма remove() Однако алгоритм возвращает итератор, указывающий на новый конец коллекции. Это значение позволяет прочитать полученный интервал, уменьшить размер коллекции или узнать количество удаленных элементов. Рассмотрим слегка измененную версию примера: stl/remove?.срр #include <iostream> #1nclude <l1st> Iinclude <algor1thm> using namespace std: int mainO { list<int> coll: Вставка элементов со значениями от 6 до 1 и от 1 до 6 for (1nt i=l; 1<=б; { coll.push frontCi): coll.push back(i); Вывод всех элементов коллекции copy (coll.beginO. coll.endO. ostream i terator<i nt>(cout. cout endl; Удаление всех элементов со значением 3 - сохранение нового конца коллекции list<int>: :iterator end = remove (coll.beginO. coll.endO Вывод элементов полученной коллекции copy (coll .beginO . end. ostream 1terator<int>(cout. )): cout endl: Вывод количества удаленных элементов cout number of removed elements: dIstanceCend.coll .endO) endl: Стирание удаленных элементов coll.erase (end, coll.endO): Вывод всех злементов модифицированной коллекции сору (coll .ЬедШО. coll.endO. ostream 1terator<1nt>(cout. )): cout endl; В новой версии программы значение, возвращаемое алгоритмом remove(), присваивается итератору end: list<int>: ;lterator end = remove (coll .beginO. coll.endO. Итератор end определяет логический конец модифицированной коллекции после удаления элементов. Полученное эначение определяет конечную границу интервала при последующих операциях: сору (coll.beginC), end, ostream iterator<int>(cout. )): Другой способ основан на обработке количества удаленных элементов, вычисляемого как расстояние между логическим и физическим концами коллекции: cout number of removed elements; distance(end,coll .endO) endl; В этом фрагменте используется специальная вспомогательная функция distance(), возвращающая расстояние между двумя итераторами. При работе с итераторами произвольного доступа расстояние вычисляется простым вычитанием оператором -, однако в нашем примере используется список, который поддерживает только двунаправленные итераторы. Дополнительная информация о функции distanceO приведена на с. 267. Чтобы удаленные элементы были действительно удалены из коллекции, следует вызвать соответствующую функцию контейнера. Для таких целей контейнеры поддерживают функцию erase(), которая удаляет все элементы из интервала, определяемого переданными аргументами: coll.erase (end. coll.endO): Результат работы программы: 654321123456 6542112456 Определение distance() было изменено, поэтому в старых версиях STL необходимо включать файл distance.hpp (см. с. 268).
|
© 2006 - 2025 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки. |