Книги
чёрным по белому
Главное меню
Главная О нас Добавить материал Поиск по сайту Карта книг Карта сайта
Книги
Археология Архитектура Бизнес Биология Ветеринария Военная промышленность География Геология Гороскоп Дизайн Журналы Инженерия Информационные ресурсы Искусство История Компьютерная литература Криптология Кулинария Культура Лингвистика Математика Медицина Менеджмент Металлургия Минералогия Музыка Научная литература Нумизматика Образование Охота Педагогика Политика Промышленные производства Психология Путеводители Религия Рыбалка Садоводство Саморазвитие Семиотика Социология Спорт Столярное дело Строительство Техника Туризм Фантастика Физика Футурология Химия Художественная литература Экология Экономика Электроника Энергетика Этика Юриспруденция
Новые книги
Цуканов Б.И. "Время в психике человека" (Медицина)

Суворов С. "Танк Т-64. Первенец танков 2-го поколения " (Военная промышленность)

Нестеров В.А. "Основы проэктирования ракет класса воздух- воздух и авиационных катапульных установок для них" (Военная промышленность)

Фогль Б. "101 вопрос, который задала бы ваша кошка своему ветеринару если бы умела говорить" (Ветеринария)

Яблоков Н.П. "Криминалистика" (Юриспруденция)
Реклама

Эффективное использование STL. Библиотека программиста - Мейерс С.

Мейерс С. Эффективное использование STL. Библиотека программиста — Спб.: Питер , 2002. — 224 c.
ISBN 5-94723-382-7
Скачать (прямая ссылка): effektivnoeispolzovaniestlbibliote2002.djvu
Предыдущая << 1 .. 54 55 56 57 58 59 < 60 > 61 62 63 64 65 66 .. 114 >> Следующая

iterator. Для компилятора это означает, что Inputlterator при вызове
distance соответствует типу deque<int>:: iterator. Однако ci относится к
типу Constlter, который представляет собой определение типа для
deque<int>: :const_iterator. Из этого следует, что Inputlterator
соответствует типу deque<int>: :const_iterator. Inputlterator никак не
может соответствовать двум типам одновременно, поэтому вызов di stance
завершается неудачей и каким-нибудь запутанным сообщением об ошибке, из
которого можно (или нельзя) понять, что компилятор не смог определить тип
Inputlterator.
Чтобы вызов нормально компилировался, необходимо ликвидировать
неоднозначность. Для этого проще всего явно задать параметр-тип,
используемый di stance, и избавить компилятор от необходимости определять
его самостоятельно:
advanced,distance<ConstIter>(i,ci)): // Вычислить расстояние между
// i и ci (как двумя constjterator)
// и переместить i на это расстояние
Итак, теперь вы знаете, как при помощи advance и distance получить
iterator, соответствующий заданному constjterator, но до настоящего
момента совершенно не рассматривался вопрос, представляющий большой
практический интерес:
Совет 28 117
насколько эффективна данная методика? Ответ прост: она эффективна
настолько, насколько это позволяют итераторы. Для итераторов
произвольного доступа, поддерживаемых контейнерами vector, string, deque
и т. д., эта операция выполняется с постоянным временем. Для двусторонних
итераторов (к этой категории относятся итераторы других стандартных
контейнеров, а также некоторых реализаций хэшированных контейнеров - см.
совет 25) эта операция выполняется с линейным временем.
Поскольку получение iterator, эквивалентного const_iterator, может
потребовать линейного времени, и поскольку это вообще невозможно сделать
при недоступности контейнера, к которому относится const_i terator,
проанализируйте архитектурные решения, вследствие которых возникла
необходимость получения iterator по const_i terator. Результат такого
анализа станет дополнительным доводом в пользу совета 26, рекомендующего
отдавать предпочтение iterator перед const- и reverse-итераторами.
Совет 28. Научитесь использовать функцию base
При вызове функции base для итератора reverse_i terator будет получен
"соответствующий" iterator, однако из сказанного совершенно не ясно, что
же при этом происходит. В качестве примера рассмотрим следующий фрагмент,
который заносит в вектор числа 1-5, устанавливает reverse i terator на
элемент 3 и инициализирует iterator функцией base:
vector<int> v:
v.reserve(5); //См. совет 14
for (int i=l:i<=5:++i){ // Занести в вектор числа 1-5
v.push_back(i);
i vector<i nt>::reverse_i terator ri= // Установить ri на элемент 3
find(v.rbegin().v.rend(),3):
vector<int>::iterator i(ri .baseO): // Присвоить i результат вызова
base
// для итератора ri
После выполнения этого фрагмента ситуация выглядит примерно так:
rend() ri() rbegin()
Т
beginQ
1 2 3 4 5
т
t
end()
На рисунке видно характерное смещение reverse_i terator и
соответствующего базового итератора, воспроизводящего смещение rbeginO и
rendO по отношению к beginC) и end (), но найти на нем ответы на
некоторые вопросы не удается. В частности, рисунок не объясняет, как
использовать i для выполнения операций, которые должны были выполняться с
ri.
118 Глава 4 • Итераторы
Как упоминалось в совете 26, некоторые функции контейнеров принимают в
качестве параметров-итераторов только iterator. Поэтому если вы,
допустим, захотите вставить новый элемент в позицию, определяемую
итератором ri, сделать это напрямую не удастся; функция i nsert
контейнера vector не принимает reverse_ iterator. Аналогичная проблема
возникает при удалении элемента, определяемого итератором гi. Функции
erase не соглашаются на reversei terator и принимают только iterator.
Чтобы выполнить удаление или вставку, необходимо преобразовать reversei
terator в iterator при помощи base, а затем воспользоваться iterator для
выполнения нужной операции.
Допустим, потребовалось вставить в v новый элемент в позиции,
определяемой итератором ri. Для определенности будем считать, что
вставляется число 99. Учитывая, что ri на предыдущем рисунке используется
для перебора справа налево, а новый элемент вставляется перед позицией
итератора, определяющего позицию вставки, можно ожидать, что число 99
окажется перед числом 3 в обратном порядке перебора. Таким образом, после
вставки вектор v будет выглядеть так:
_Л. го со со со 4 5
Конечно, мы не можем использовать ri для обозначения позиции вставки,
поскольку это не iterator. Вместо этого необходимо использовать i. Как
упоминалось выше, когда ri указывает на элемент 3, i (то есть ri. base())
указывает на элемент 4. Именно на эту позицию должен указывать итератор
i, чтобы вставленный элемент оказался в той позиции, в которой он бы
находился, если бы для вставки можно было использовать итератор ri.
Предыдущая << 1 .. 54 55 56 57 58 59 < 60 > 61 62 63 64 65 66 .. 114 >> Следующая