Читаем C++17 STL Стандартная библиотека шаблонов полностью

Пример работает потому, что в момент итерации по контейнеру std::map мы получаем узлы std::pair на каждом шаге этого процесса. Именно эти узлы распаковываются с помощью структурированных привязок (key_type представляет собой строку с именем species, а value_type — переменную count типа size_t), что позволяет получить к ним доступ по отдельности в теле цикла.

До появления C++17 аналогичного эффекта можно было достичь с помощью std::tie:

int remainder;

std::tie(std::ignore, remainder) = divide_remainder(16, 5);

std::cout << "16 % 5 is " << remainder << '\n';

Здесь показано, как распаковать полученную пару в две переменные. Применение контейнера std::tie не так удобно, как использование декомпозиции, ведь нам надо заранее объявить все переменные, которые мы хотим связать. С другой стороны, пример демонстрирует преимущество std::tie перед структурированными привязками: значение std::ignore играет роль переменной-пустышки. В данном случае частное нас не интересует и мы отбрасываем его, связав с std::ignore.

  Когда мы применяем декомпозицию, у нас нет переменных-пустышек tie, поэтому нужно привязывать все значения к именованным переменным. Это может оказаться неэффективным, если позже не задействовать некоторые переменные, но тем не менее компилятор может оптимизировать неиспользованное связывание.

Раньше функцию divide_remainder можно было реализовать следующим образом, используя выходные параметры:

bool divide_remainder(int dividend, int divisor,

                      int &fraction, int &remainder);

Получить к ним доступ можно так:

int fraction, remainder;

const bool success {divide_remainder(16, 3, fraction, remainder)};

if (success) {

  std::cout << "16/3 is " << fraction << " with a remainder of "

            << remainder << '\n';

}

Многие все еще предпочитают делать именно так, а не возвращать пары, кортежи и структуры. При этом они приводят следующие аргументы: код работает быстрее, поскольку мы не создаем промежуточные копии этих значений. Но для современных компиляторов это неверно — они изначально оптимизированы так, что подобные копии не создаются.

  Помимо того, что аналогичной возможности нет в языке C, возврат сложных структур в качестве выходных параметров долгое время считался медленным, поскольку объект сначала нужно инициализировать в возвращающей функции, а затем скопировать в переменную, которая должна будет содержать возвращаемое значение на вызывающей стороне. Современные компиляторы поддерживают оптимизацию возвращаемых значений (return value optimization, RVO), что позволяет избежать создания промежуточных копий.

<p id="AutBody_Root11">Ограничиваем область видимости переменных в выражениях if и switch</p>

Максимальное ограничение области видимости переменных считается хорошим тоном. Иногда, однако, переменная должна получить какое-то значение, а потом нужно его проверить на соответствие тому или иному условию, чтобы продолжить выполнение программы. Для этих целей в С++17 была введена инициализация переменных в выражениях if и switch.

Как это делается

В данном примере мы воспользуемся новым синтаксисом в обоих контекстах, чтобы увидеть, насколько это улучшит код.

□ Выражение if. Допустим, нужно найти символ в таблице символов с помощью метода find контейнера std::map:

if (auto itr (character_map.find(c)); itr != character_map.end()) {

  // *itr корректен. Сделаем с ним что-нибудь.

} else {

  // itr является конечным итератором. Не разыменовываем.

}

// здесь itr недоступен

□ Выражение switch. Так выглядит код получения символа из пользовательского ввода и его одновременная проверка в выражении switch для дальнейшего управления персонажем компьютерной игры:

switch (char c (getchar()); c) {

  case 'a': move_left();  break;

  case 's': move_back(); break;

  case 'w': move_fwd(); break;

  case 'd': move_right(); break;

  case 'q': quit_game(); break;

  case '0'...'9': select_tool('0' - c); break;

  default:

    std::cout << "invalid input: " << c << '\n';

} 

Как это работает

Перейти на страницу:

Все книги серии Библиотека программиста

Программист-фанатик
Программист-фанатик

В этой книге вы не найдете описания конкретных технологий, алгоритмов и языков программирования — ценность ее не в этом. Она представляет собой сборник практических советов и рекомендаций, касающихся ситуаций, с которыми порой сталкивается любой разработчик: отсутствие мотивации, выбор приоритетов, психология программирования, отношения с руководством и коллегами и многие другие. Подобные знания обычно приходят лишь в результате многолетнего опыта реальной работы. По большому счету перед вами — ярко и увлекательно написанное руководство, которое поможет быстро сделать карьеру в индустрии разработки ПО любому, кто поставил себе такую цель. Конечно, опытные программисты могут найти некоторые идеи автора достаточно очевидными, но и для таких найдутся темы, которые позволят пересмотреть устоявшиеся взгляды и выйти на новый уровень мастерства. Для тех же, кто только в самом начале своего пути как разработчика, чтение данной книги, несомненно, откроет широчайшие перспективы. Издательство выражает благодарность Шувалову А. В. и Курышеву А. И. за помощь в работе над книгой.

Чед Фаулер

Программирование, программы, базы данных / Программирование / Книги по IT

Похожие книги

1С: Бухгалтерия 8 с нуля
1С: Бухгалтерия 8 с нуля

Книга содержит полное описание приемов и методов работы с программой 1С:Бухгалтерия 8. Рассматривается автоматизация всех основных участков бухгалтерии: учет наличных и безналичных денежных средств, основных средств и НМА, прихода и расхода товарно-материальных ценностей, зарплаты, производства. Описано, как вводить исходные данные, заполнять справочники и каталоги, работать с первичными документами, проводить их по учету, формировать разнообразные отчеты, выводить данные на печать, настраивать программу и использовать ее сервисные функции. Каждый урок содержит подробное описание рассматриваемой темы с детальным разбором и иллюстрированием всех этапов.Для широкого круга пользователей.

Алексей Анатольевич Гладкий

Программирование, программы, базы данных / Программное обеспечение / Бухучет и аудит / Финансы и бизнес / Книги по IT / Словари и Энциклопедии
1С: Управление торговлей 8.2
1С: Управление торговлей 8.2

Современные торговые предприятия предлагают своим клиентам широчайший ассортимент товаров, который исчисляется тысячами и десятками тысяч наименований. Причем многие позиции могут реализовываться на разных условиях: предоплата, отсрочка платежи, скидка, наценка, объем партии, и т.д. Клиенты зачастую делятся на категории – VIP-клиент, обычный клиент, постоянный клиент, мелкооптовый клиент, и т.д. Товарные позиции могут комплектоваться и разукомплектовываться, многие товары подлежат обязательной сертификации и гигиеническим исследованиям, некондиционные позиции необходимо списывать, на складах периодически должна проводиться инвентаризация, каждая компания должна иметь свою маркетинговую политику и т.д., вообщем – современное торговое предприятие представляет живой организм, находящийся в постоянном движении.Очевидно, что вся эта кипучая деятельность требует автоматизации. Для решения этой задачи существуют специальные программные средства, и в этой книге мы познакомим вам с самым популярным продуктом, предназначенным для автоматизации деятельности торгового предприятия – «1С Управление торговлей», которое реализовано на новейшей технологической платформе версии 1С 8.2.

Алексей Анатольевич Гладкий

Финансы / Программирование, программы, базы данных