Читать книги » Книги » Компьютеры и Интернет » Программирование » C++17 STL Стандартная библиотека шаблонов - Яцек Галовиц

C++17 STL Стандартная библиотека шаблонов - Яцек Галовиц

Читать книгу C++17 STL Стандартная библиотека шаблонов - Яцек Галовиц, Яцек Галовиц . Жанр: Программирование.
C++17 STL Стандартная библиотека шаблонов - Яцек Галовиц
Название: C++17 STL Стандартная библиотека шаблонов
Дата добавления: 15 июль 2023
Количество просмотров: 1 473
(18+) Внимание! Книга может содержать контент только для совершеннолетних. Для несовершеннолетних просмотр данного контента СТРОГО ЗАПРЕЩЕН! Если в книге присутствует наличие пропаганды ЛГБТ и другого, запрещенного контента - просьба написать на почту для удаления материала.
Читать онлайн

C++17 STL Стандартная библиотека шаблонов читать книгу онлайн

C++17 STL Стандартная библиотека шаблонов - читать онлайн , автор Яцек Галовиц

С++ — объектно-ориентированный язык программирования, без которого сегодня немыслима промышленная разработка ПО. В этой замечательной книге описана работа с контейнерами, алгоритмами, вспомогательными классами, лямбда-выражениями и другими интересными инструментами, которыми богат современный С++. Освоив материал, вы сможете коренным образом пересмотреть привычный подход к программированию.
Преимущество издания — в подробном описании стандартной библиотеки шаблонов С++, STL. Ее свежая версия была выпущена в 2017 году. В книге вы найдете более 90 максимально реалистичных примеров, которые демонстрируют всю мощь STL. Многие из них станут базовыми кирпичиками для решения более универсальных задач.
Вооружившись этой книгой, вы сможете эффективно использовать С++17 для создания высококачественного и высокопроизводительного ПО, применимого в различных отраслях.

1 ... 76 77 78 79 80 ... 121 ВПЕРЕД
Перейти на страницу:
с плавающей точкой, в верхнем регистре и явным префиксом +, если они имеют положительные значения. Кроме того, мы используем наш класс format_guard, чтобы очистить все настройки при выходе из функции:

template <typename T>

ostream& operator<<(ostream &os, const scientific_type<T> &w) {

  format_guard _;

  os << scientific << uppercase << showpos;

  return os << w.value;

}

5. В функции main сначала поработаем с классом format_guard. Откроем новую область видимости, получим экземпляр класса, а затем применим некоторые флаги форматирования к потоку вывода std::cout:

int main()

{

  {

    format_guard _;

    cout << hex << scientific << showbase << uppercase;

    cout << "Numbers with special formatting:n";

    cout << 0x123abc << 'n';

    cout << 0.123456789 << 'n';

  }

6. После того как выведем некоторые числа с помощью флагов форматирования, покинем область видимости. В результате деструктор класса format_guard сбросит настройки форматирования. Чтобы это протестировать, выведем точно такие же числа снова. Они должны выглядеть по-другому:

  cout << "Same numbers, but normal formatting again:n";

  cout << 0x123abc << 'n';

  cout << 0.123456789 << 'n';

7. Теперь воспользуемся классом scientific_type. Выведем на экран три числа с плавающей точкой в ряд. Второе число обернем в класс scientific_type.

Соответственно, оно будет выведено с применением нашего особенного стиля форматирования, а числа, стоящие перед ним и после него, будут иметь форматирование по умолчанию. В то же время мы избежим появления ненужных символов.

  cout << "Mixed formatting: "

       << 123.0 << " "

       << scientific_type{123.0} << " "

       << 123.456 << 'n';

}

8. Компиляция и запуск программы дадут следующий результат. Первые два числа будут выведены с конкретным форматированием. Следующие два будут иметь форматирование по умолчанию — это показывает, что наш класс format_guard работает хорошо. Три числа в последних строках также выглядят соответственно нашим ожиданиям. Число, которое стоит посередине, имеет форматирование класса scientific_type, остальные же имеют форматирование по умолчанию:

$ ./pretty_print_on_the_fly

Numbers with special formatting:

0X123ABC

1.234568E-01

Same numbers, but normal formatting again:

1194684

0.123457

Mixed formatting: 123 +1.230000E+02 123.456 

Перехватываем читабельные исключения для ошибок потока std::iostream

Ни в одном из примеров, показанных в данной главе, мы не использовали для обнаружения ошибок исключения. Несмотря на такую возможность, можно работать с объектами потоков без исключений — это очень удобно. Если мы попробуем преобразовать десять значений, но где-то в середине будет сгенерирована ошибка, то весь объект потока войдет в ошибочное состояние и перестанет работать. Таким образом, мы не столкнемся с ситуацией, когда преобразуем переменные с ошибочным смещением в потоке. Мы можем выполнять условные преобразования, например, так: if (cin >> foo >> bar >> ...). В случае сбоя этой конструкции мы его обработаем. Использование конструкции try {...} catch... при преобразовании объектов не кажется очень полезным.

Фактически библиотека для работы с потоками ввода/вывода в C++ существовала уже в те времена, когда язык C++ еще не работал с исключениями. Поддержка исключений была добавлена позже, это объясняет отсутствие их первоклассной поддержки в потоковой библиотеке.

Применение исключений для потоковой библиотеки возможно при конфигурации каждого отдельного объекта потока таким образом, чтобы он генерировал исключение в тот момент, когда входит в ошибочное состояние. К сожалению, пояснения к ошибкам, лежащие в объектах исключений, которые мы будем отлавливать, не стандартизированы. Это приводит к появлению не очень информативных сообщений об ошибках, их мы рассмотрим в данном разделе. Если вы действительно хотите использовать исключения для объектов потока, то можете дополнительно опросить библиотеку языка C для состояния ошибок файловой системы, чтобы получить добавочную информацию.

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

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

В этом примере мы реализуем программу, которая открывает файл (тут может быть сгенерирован сбой), а затем считаем оттуда целое число (здесь тоже возможен сбой). Сделаем это с помощью активизированных исключений, а затем увидим, как их обработать.

1. Сначала включим некоторые заголовочные файлы и объявим об использовании пространства имен std:

#include <iostream>

#include <fstream>

#include <system_error>

#include <cstring>

using namespace std;

2. Для использования объектов потока вместе с исключениями нужно их активизировать. Чтобы объект файлового потока генерировал исключение в том случае, если нужный файл не существует или при преобразовании возникли ошибки, следует установить значения некоторых битов, указывающих на сбой, в маске исключения. Если мы затем сделаем нечто вызывающее сбой, это сгенерирует исключение. Активизируя failbit и badbit, мы включаем генерацию исключений для ошибок файловой системы и преобразования:

int main()

{

  ifstream f;

  f.exceptions(f.failbit | f.badbit);

3. Теперь можно открыть блок try и обратиться к файлу. Если последний был открыт успешно, то попробуем считать из него целое число. При успешном выполнении обоих шагов выведем целое число:

  try {

    f.open("non_existant.txt");

    int i;

    f >> i;

    cout << "integer has value: " << i << 'n';

  }

4. Если хотя бы в одной из этих ситуаций возникнет ошибка, то будет сгенерирован экземпляр std::ios_base::failure. Данный объект имеет функцию-член what(), которая должна объяснить, что вызвало генерацию исключения. К сожалению, это сообщение не стандартизировано и не слишком информативно. Однако мы можем хотя бы определить, это проблема с файловой системой (например, файл не существует) или же ошибка преобразования. Глобальная переменная errno существовала с момента создания C++, и она получает значение ошибки, которое мы сейчас можем получить. Функция strerror преобразует номер ошибки в строку, понятную для человека. Если код равен 0, то значит, у нас возникла не ошибка файловой системы.

  catch (ios_base::failure& e) {

    cerr << "Caught error: ";

    if (errno) {

      cerr << strerror(errno) << 'n';

    } else {

      cerr << e.what() << 'n';

1 ... 76 77 78 79 80 ... 121 ВПЕРЕД
Перейти на страницу:
Комментарии (0)