Эффективное использование STL - [50]
>pair
, что в свою очередь приведет к вызову конструктора и деструктора >Widget
, поскольку >pair
содержит объект >Widget
. При вызове >operator[]
объект >pair
не используется, что позволяет избежать затрат на конструирование и уничтожение >pair
и >Widget
.Следовательно, при вставке элемента в >map
по соображениям эффективности желательно использовать >insert
вместо >operator[]
, а при обновлении существующих элементов предпочтение отдается >operator[]
, что объясняется как эффективностью, так и эстетическими соображениями.
Конечно, нам хотелось бы видеть в STL функцию, которая бы автоматически выбирала оптимальное решение в синтаксически привлекательном виде. Интерфейс вызова мог бы выглядеть следующим образом:
>iterator affectedPair = // Если ключ к отсутствует в контейнере m,
> efficentAddOrUpdate(m, k, v); // выполнить эффективное добавление
> // pair(k, v) в m; в противном случае
> // выполнить эффективное обновление
> // значения, ассоциированного с ключом k.
> // Функция возвращает итератор
> // для добавленной или измененной пары
В STL такая функция отсутствует, но как видно из следующего фрагмента, ее нетрудно написать самостоятельно. В комментариях даются краткие пояснения, а дополнительная информация приведена после листинга.
>template
> typename KeyArgType, // Причины для передачи параметров-типов
> typename ValueArgType> // KeyArgType и ValueArgType
> // приведены ниже
>typename МарТуре::iterator efficientAddOrUpdate(MapType& m,
> const KeyArgType& k, const ValueArgType& v) {
> typename МарТуре:iterator lb = // Определить, где находится
> // или должен находиться ключ k.
> m.lower_bound(k); // Ключевое слово typename
> // рассматривается на с. 20
> if (lb != m.end())&& !(m.key_comp()(k.lb->first))){ // Если lb ссылается на пару,
> // ключ которой эквивалентен k,
> lb->second = v; // …обновить ассоциируемое значение
> return lb; // и вернуть итератор для найденной пары
> } else {
> typedef typename МарТуре::value_type MVT;
> return m.insert(lb.MVT(k, v)); // Включить pair(k, v) в m и вернуть
> // итератор для нового элемента
> }
>}
Для эффективного выполнения операций создания и обновления необходимо узнать, присутствует ли ключ к в контейнере; если присутствует — где он находится, а если нет — где он должен находиться. Задача идеально подходит для функции >lower_bound
(совет 45). Чтобы определить, обнаружила ли функция >lower_bound
элемент с нужным ключом, мы проверяем вторую половину условия эквивалентности (см. совет 19). При этом сравнение должно производиться функцией, полученной при вызове >map::keycomp
. В результате проверки эквивалентности мы узнаем, какая операция выполняется — создание или обновление.
Обновление реализовано весьма прямолинейно. С созданием дело обстоит поинтереснее, поскольку в нем используется «рекомендательная» форма >insert
. Конструкция >m.insert(lb.MVT(k, v))
«рекомендует» >lb
как правильную точку вставки для нового элемента с ключом, эквивалентным >k
, а Стандарт гарантирует, что в случае правильности рекомендации вставка будет выполнена за постоянное время (вместо логарифмического). В >efficentAddOrUpdate
мы знаем, что >lb
определяет правильную позицию вставки, поэтому >insert
всегда выполняется с постоянным временем.
У данной реализации есть одна интересная особенность — >KeyArgType
и >ValueArgType
не обязаны быть типами, хранящимися в контейнере, а всего лишь должны приводитьсяк этим типам. Существует и другое возможное решение — удалить параметры-типы >KeyArgType/ValueArgType
и заменить их на >МарТуре::key_type
и >МарТуре::mapped_type
. Но в этом случае вызов может сопровождаться лишними преобразованиями типов. Возьмем определение контейнера >map
, встречавшееся в примерах:
>map
Также вспомним, что Widget допускает присваивание значений типа >double
:
>class Widget { // См. ранее
>public:
> Widget& operator=(double weight);
>};
Теперь рассмотрим следующий вызов >efficientAddOrUpdate
:
>effcientAddOrUpdate(m, 10, 15);
Допустим, выполняется операция обновления, то есть >m
уже содержит элемент с ключом 10. В этом случае приведенный ранее шаблон заключает, что >ValueArgType
является >double
, и в теле функции число 1.5 в формате >double
напрямую присваивается объекту >Widget
, ассоциированному с ключом 10. Присваивание осуществляется вызовом >Widget::operator=(double)
. Если бы третий параметр >efficientAddOrUpdate
относился к типу >МарТуре::mapped_type
, то число 1.5 в момент вызова было бы преобразовано в >Widget
, что привело бы к лишним затратам на конструирование (и последующее уничтожение) объекта >Widget
.
Сколь бы интересными не были тонкости реализации
Эффективный и современный С++Освоение С++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, гарантирующее конфиденциальность пользовательской информации. Если вы решились разобраться в том что такое программирование, не нужно ждать.
Алгоритмы - это всего лишь пошаговые алгоритмы решения задач, и большинство таких задач уже были кем-то решены, протестированы и проверены. Можно, конечно, погрузится в глубокую философию гениального Кнута, изучить многостраничные фолианты с доказательствами и обоснованиями, но хотите ли вы тратить на это свое время? Откройте великолепно иллюстрированную книгу и вы сразу поймете, что алгоритмы - это просто. А грокать алгоритмы - это веселое и увлекательное занятие.