Эффективное использование STL - [53]
>const_iterator
, не >reverse_iterator
и не >const_reverse_iterator
— только >iterator
. Хотя контейнеры поддерживают четыре типа итераторов, один из этих типов обладает привилегиями, отсутствующими у других типов. Тип >iterator
занимает особое место.На следующей диаграмме показаны преобразования, возможные между итераторами разных типов.
Из рисунка следует, что >iterator
преобразуется в >const_iterator
и >reverse_iterator
, а >reverse_iterator
— в >const_reverse_iterator
. Кроме того, >reverse_iterator
преобразуется в >iterator
при помощи функции >base
типа >reverse_iterator
, а >const_reverse_iterator
аналогичным образом преобразуется в >const_iterator
. Однако из рисунка не видно, что итераторы, полученные при вызове >base
, могут оказаться не теми, которые вам нужны. За подробностями обращайтесь к совету 28.
Обратите внимание: не существует пути от >const_iterator
к >iterator
или от >const_reverse_iterator
к >reverse_iterator
. Из этого важного обстоятельства следует, что >const_iterator
и >const_reverse_iterator
могут вызвать затруднения с некоторыми функциями контейнеров. Таким функциям необходим тип >iterator
, а из-за отсутствия обратного перехода от >const
-итераторов к >iterator
первые становятся в целом бесполезными, если вы хотите использовать их для определения позиции вставки или удаления элементов.
Однако не стоит поспешно заключать, что >const
-итераторы вообще бесполезны. Это не так. Они прекрасно работают с алгоритмами, поскольку для алгоритмов обычно подходят все типы итераторов, относящиеся к нужной категории. Кроме того, >const
-итераторы подходят для многих функций контейнеров. Проблемы возникают лишь с некоторыми формами >insert
и >erase
.
Обратите внимание на формулировку: >const
-итераторы становятся в целом бесполезными, если вы хотите использовать их для определения позиции вставки или удаления элементов. Называть их полностью бесполезными было бы неправильно. Const-итераторы могут принести пользу, если вы найдете способ получения >iterator
для >const_iterator
или >const_reverse_iterator
. Такое возможно часто, но далеко не всегда, причем даже в благоприятном случае решение не очевидно, да и эффективным его не назовешь. В двух словах этот вопрос не изложить, если вас заинтересуют подробности — обращайтесь к совету 27. А пока имеющаяся информация позволяет понять, почему типу >iterator
отдается предпочтение перед его >const
- и >reverse
-аналогами.
• Некоторым версиям >insert
и >erase
при вызове должен передаваться тип >iterator
. >Const
- и >reverse
-итераторы им не подходят.
• Автоматическое преобразование >const
-итератора в >iterator
невозможно, а методика получения >iterator
на основании >const_iterator
(совет 27) применима не всегда, да и эффективность ее не гарантируется.
• Преобразование >reverse_iterator
в >iterator
может требовать дополнительной регулировки итератора. В совете 28 рассказано, когда и почему возникает такая необходимость.
Из сказанного следует однозначный вывод: если вы хотите работать с контейнерами просто и эффективно и по возможности застраховаться от нетривиальных ошибок, выбирайте >iterator
вместо его >const
- и >reverse
-аналогов.
На практике выбирать обычно приходится между >iterator
и >const_iterator
. Выбор между >iterator
и >reverse_iterator
часто происходит помимо вашей воли — все зависит от того, в каком порядке должны перебираться элементы контейнера (в прямом или в обратном). А если после выбора >reverse_iterator
потребуется вызвать функцию контейнера, требующую >iterator
, вызовите функцию >base
(возможно, с предварительной регулировкой смещения — см. совет 28).
При выборе между >iterator
и >const_iterator
рекомендуется выбирать >iterator
даже в том случае, если можно обойтись >const_iterator
, а использование >iterator
не обусловлено необходимостью вызова функции контейнера. В частности, немало хлопот возникает при сравнениях >iterator
с >const_iterator
. Думаю, вы согласитесь, что следующий фрагмент выглядит вполне логично:
>typedef deque
>typedef IntDeque:iterator Iter; // упрощают работу
>typedef IntDeque::const_iterator ConstIter; // с контейнерами STL
> // и типами итераторов
>iter i;
>ConstIter ci;
>… // i и ci указывают на элементы
> // одного контейнера
>if (i==ci)… // Сравнить iterator
> //c const_iterator
В данном примере происходит обычное сравнение двух итераторов контейнера, подобные сравнения совершаются в STL сплошь и рядом. Просто один объект относится к типу >iterator
, а другой — к типу >const_iterator
. Проблем быть не должно — >iterator
автоматически преобразуется в >const_iterator
, и в сравнении участвуют два >const_iterator
.
Именно это и происходит в хорошо спроектированных реализациях STL, но в некоторых случаях приведенный фрагмент не компилируется. Причина заключается в том, что такие реализации объявляют >operator==
функцией класса >const_iterator
вместо внешней функции. Впрочем, вас, вероятно, больше интересуют не корни проблемы, а ее решение, которое заключается в простом изменении порядка итераторов:
>if (c==i)… // Обходное решение для тех случаев,
Эффективный и современный С++Освоение С++11 и С++14 — это больше, чем просто ознакомление с вводимыми этими стандартами возможностями (например, объявлениями типов auto, семантикой перемещения, лямбда-выражениями или поддержкой многопоточности). Вопрос в том, как использовать их эффективно, чтобы создаваемые программы были корректны, эффективны и переносимы, а также чтобы их легко можно было сопровождать. Именно этим вопросам и посвящена данная книга, описывающая создание по-настоящему хорошего программного обеспечения с использованием C++11 и С++14 — т.е.
Когда приходится инкапсулировать, то иногда лучше меньше, чем большеЯ начну со следующего утверждения: Если вы пишете функцию, которая может быть выполнена или как метод класса, или быть внешней по отношению к классу, Вы должны предпочесть ее реализацию без использования метода. Такое решение увеличивает инкапсуляцию класса. Когда Вы думаете об использовании инкапсуляции, Вы должны думать том, чтобы не использовать методы.Удивлены? Читайте дальше.
Разработчику часто требуется много сторонних инструментов, чтобы создавать и поддерживать проект. Система Git — один из таких инструментов и используется для контроля промежуточных версий вашего приложения, позволяя вам исправлять ошибки, откатывать к старой версии, разрабатывать проект в команде и сливать его потом. В книге вы узнаете об основах работы с Git: установка, ключевые команды, gitHub и многое другое.В книге рассматриваются следующие темы:основы Git;ветвление в Git;Git на сервере;распределённый Git;GitHub;инструменты Git;настройка Git;Git и другие системы контроля версий.
В книге рассказывается история главного героя, который сталкивается с различными проблемами и препятствиями на протяжении всего своего путешествия. По пути он встречает множество второстепенных персонажей, которые играют важные роли в истории. Благодаря опыту главного героя книга исследует такие темы, как любовь, потеря, надежда и стойкость. По мере того, как главный герой преодолевает свои трудности, он усваивает ценные уроки жизни и растет как личность.
В книге рассказывается история главного героя, который сталкивается с различными проблемами и препятствиями на протяжении всего своего путешествия. По пути он встречает множество второстепенных персонажей, которые играют важные роли в истории. Благодаря опыту главного героя книга исследует такие темы, как любовь, потеря, надежда и стойкость. По мере того, как главный герой преодолевает свои трудности, он усваивает ценные уроки жизни и растет как личность.
В книге рассказывается история главного героя, который сталкивается с различными проблемами и препятствиями на протяжении всего своего путешествия. По пути он встречает множество второстепенных персонажей, которые играют важные роли в истории. Благодаря опыту главного героя книга исследует такие темы, как любовь, потеря, надежда и стойкость. По мере того, как главный герой преодолевает свои трудности, он усваивает ценные уроки жизни и растет как личность.
Python - объектно-ориентированный язык сверхвысокого уровня. Python, в отличии от Java, не требует исключительно объектной ориентированности, но классы в Python так просто изучить и так удобно использовать, что даже новые и неискушенные пользователи быстро переходят на ОО-подход.
Что общего между самыми востребованными профессиями и стремительным увеличением количества информации в мире? Ответ: язык структурированных запросов (SQL). SQL — рабочая лошадка среди языков программирования, основа основ для современного анализа и управления данными. Книга «SQL: быстрое погружение» идеальна для всех, кто ищет новые перспективы карьерного роста; для разработчиков, которые хотят расширить свои навыки и знания в программировании; для любого человека, даже без опыта, кто хочет воспользоваться возможностями будущего, в котором будут править данные.
Даже плохой программный код может работать. Однако если код не является «чистым», это всегда будет мешать развитию проекта и компании-разработчика, отнимая значительные ресурсы на его поддержку и «укрощение». Эта книга посвящена хорошему программированию. Она полна реальных примеров кода. Мы будем рассматривать код с различных направлений: сверху вниз, снизу вверх и даже изнутри. Прочитав книгу, вы узнаете много нового о коде. Более того, вы научитесь отличать хороший код от плохого. Вы узнаете, как писать хороший код и как преобразовать плохой код в хороший. Книга состоит из трех частей.
Книга "Изучаем Python" - это ускоренный курс, который позволит вам сэкономить время и сразу начать писать работоспособные программы (игры, визуализации данных, веб-приложения и многое другое). Хотите стать программистом? В первой части книги вам предстоит узнать о базовых принципах программирования, познакомиться со списками, словарями, классами и циклами, вы научитесь создавать программы и тестировать код. Во второй части книги вы начнете использовать знания на практике, работая над тремя крупными проектами: создадите собственную "стрелялку" с нарастающей сложностью уровней, займетесь работой с большими наборами данных и освоите их визуализацию, и, наконец, создадите полноценное веб-приложение на базе Django, гарантирующее конфиденциальность пользовательской информации. Если вы решились разобраться в том что такое программирование, не нужно ждать.
Алгоритмы - это всего лишь пошаговые алгоритмы решения задач, и большинство таких задач уже были кем-то решены, протестированы и проверены. Можно, конечно, погрузится в глубокую философию гениального Кнута, изучить многостраничные фолианты с доказательствами и обоснованиями, но хотите ли вы тратить на это свое время? Откройте великолепно иллюстрированную книгу и вы сразу поймете, что алгоритмы - это просто. А грокать алгоритмы - это веселое и увлекательное занятие.