Эффективное использование STL - [55]
>typedef IntDeque::const_iterator ConstIter;
>IntDeque d;
>ConstIter ci;
>… // Присвоить ci ссылку на d
>Iter i(d.begin()); // Инициализировать i значением d.begin()
>advance(i, distance(i, ci)); // Переместить i в позицию ci
Решение выглядит настолько простым и прямолинейным, что это невольно вызывает подозрения. Чтобы получить >iterator
, указывающий на тот же элемент контейнера, что и >const_iterator
, мы создаем новый >iterator
в начале контейнера и перемещаем его вперед до тех пор, пока он не удалится на то же расстояние, что и >const_iterator
! Задачу упрощают шаблоны функций >advance
и >distance
, объявленные в >
. >Distance
возвращает расстояние между двумя итераторами в одном контейнере, a >advance
перемещает итератор на заданное расстояние. Когда итераторы >i
и >ci
относятся к одному контейнеру, выражение >advance(i, distance(i, ci))
переводит их в одну позицию контейнера.
Все хорошо, если бы этот вариант компилировался… но этого не происходит. Чтобы понять причины, рассмотрим объявление >distance
:
>template
>typename iterator_traits
>distance(InputIterator first, InputIterator last);
Не обращайте внимания на то, что тип возвращаемого значения состоит из 56 символов и содержит упоминания зависимых типов (таких как differenceype). Вместо этого проанализируем использование параметра-типа >InputIterator
:
>template
>typename iterator_traits<InputIterator>::difference_type
>distance(InputIterator first, InputIterator last);
При вызове >distance
компилятор должен определить тип, представленный >InputIterator
, для чего он анализирует аргументы, переданные при вызове. Еще раз посмотрим на вызов >distance
в приведенном выше коде:
>advance(i, distance(i,ci)); // Переместить i в позицию ci
При вызове передаются два параметра, >i
и >ci
. Параметр >i
относится к типу >iter
, который представляет собой определение типа для> deque
. Для компилятора это означает, что >InputIterator
при вызове >distance
соответствует типу >deque
. Однако >ci
относится к типу >ConstIter
, который представляет собой определение типа для >deque
. Из этого следует, что >InputIterator
соответствует типу >deque
. >InputIterator
никак не может соответствовать двум типам одновременно, поэтому вызов >distance
завершается неудачей и каким-нибудь запутанным сообщением об ошибке, из которого можно (или нельзя) понять, что компилятор не смог определить тип >InputIterator
.
Чтобы вызов нормально компилировался, необходимо ликвидировать неоднозначность. Для этого проще всего явно задать параметр-тип, используемый >distance
, и избавить компилятор от необходимости определять его самостоятельно:
>advanced.distance<ConstIter>(i, ci)); // Вычислить расстояние между
> // i и ci (как двумя const_iterator)
> // и переместить i на это расстояние
Итак, теперь вы знаете, как при помощи >advance
и >distance
получить >iterator
, соответствующий заданному >const_iterator
, но до настоящего момента совершенно не рассматривался вопрос, представляющий большой практический интерес: насколько эффективна данная методика? Ответ прост: она эффективна настолько, насколько это позволяют итераторы. Для итераторов произвольного доступа, поддерживаемых контейнерами >vector
, >string
, >deque
и т. д., эта операция выполняется с постоянным временем. Для двусторонних итераторов (к этой категории относятся итераторы других стандартных контейнеров, а также некоторых реализаций хэшированных контейнеров — см. совет 25) эта операция выполняется с линейным временем.
Поскольку получение >iterator
, эквивалентного >const_iterator
, может потребовать линейного времени, и поскольку это вообще невозможно сделать при недоступности контейнера, к которому относится >const_iterator
, проанализируйте архитектурные решения, вследствие которых возникла необходимость получения >iterator
по >const_iterator
. Результат такого анализа станет дополнительным доводом в пользу совета 26, рекомендующего отдавать предпочтение >iterator
перед >const
- и >reverse
-итераторами.
Совет 28. Научитесь использовать функцию base
При вызове функции >base
для итератора >reverse_iterator
будет получен «соответствующий» >iterator
, однако из сказанного совершенно не ясно, что же при этом происходит. В качестве примера рассмотрим следующий фрагмент, который заносит в вектор числа 1–5, устанавливает >reverse_iterator
на элемент 3 и инициализирует >iterator
функцией >base
:
>vector
>v.reserve(5); //См. совет 14
>for (int i=1; i<=5; ++i){ // Занести в вектор числа 1-5
> v.push_back(i);
>}
>vector
> find(v.rbegin(), v.rend(), 3);
>vector
> // для итератора ri
После выполнения этого фрагмента ситуация выглядит примерно так:
На рисунке видно характерное смещение >reverse_iterator
и соответствующего базового итератора, воспроизводящего смещение >begin()
Эффективный и современный С++Освоение С++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, гарантирующее конфиденциальность пользовательской информации. Если вы решились разобраться в том что такое программирование, не нужно ждать.
Алгоритмы - это всего лишь пошаговые алгоритмы решения задач, и большинство таких задач уже были кем-то решены, протестированы и проверены. Можно, конечно, погрузится в глубокую философию гениального Кнута, изучить многостраничные фолианты с доказательствами и обоснованиями, но хотите ли вы тратить на это свое время? Откройте великолепно иллюстрированную книгу и вы сразу поймете, что алгоритмы - это просто. А грокать алгоритмы - это веселое и увлекательное занятие.