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

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

1 ... 8 9 10 11 12 ... 121 ВПЕРЕД
Перейти на страницу:
первые два представляют собой начальный и конечный итераторы того или иного итерабельного промежутка, а третий параметр — это значение, с которым будут сравниваться все элементы промежутка. Метод std::count возвращает количество всех элементов внутри диапазона, равных третьему параметру.

В нашем выражении свертки мы всегда передаем в функцию std::count начальный и конечный итераторы одного диапазона параметров. Однако в качестве третьего параметра мы всякий раз отправляем один параметр из пакета. В конечном счете функция складывает все результаты и возвращает их вызывающей стороне.

Ее можно использовать следующим образом:

std::vector<int> v {1, 2, 3, 4, 5};

matches(v, 2, 5);                  // возвращает 2

matches(v, 100, 200);              // возвращает 0

matches("abcdefg", 'x', 'y', 'z'); // возвращает 0

matches("abcdefg", 'a', 'd', 'f'); // возвращает 3

Как видите, вспомогательная функция matches довольно гибкая — ее можно вызвать для векторов или даже строк. Она также будет работать для списка инициализаторов, контейнеров std::list, std::array, std::set и прочих!

Проверка успешности вставки нескольких элементов в множество

Напишем вспомогательную функцию, которая добавляет произвольное количество параметров в контейнер std::set и возвращает булево значение, показывающее, успешно ли прошла операция:

template <typename T, typename ... Ts>

bool insert_all(T &set, Ts ... ts)

{

  return (set.insert(ts).second && ...);

}

Как же это работает? Функция insert контейнера std::set имеет следующую сигнатуру:

std::pair<iterator, bool> insert(const value_type& value);

Документация гласит, что при попытке вставить элемент функция insert вернет пару из iterator и переменной bool. Если вставка пройдет успешно, значение переменной будет равно true. Итератор же в этом случае укажет на новый элемент множества, а в противном случае — на существующий элемент, который помешал вставке.

Наша вспомогательная функция после вставки обращается к полю .second. Оно содержит переменную bool, которая показывает, была ли вставка успешной. Если все полученные пары имеют значение true, то все вставки прошли успешно. Свертка объединяет все результаты вставки с помощью оператора && и возвращает результат.

Контейнер можно использовать следующим образом:

std::set<int> my_set {1, 2, 3};

insert_all(my_set, 4, 5, 6); // Возвращает true

insert_all(my_set, 7, 8, 2); // Возвращает false, поскольку 2 уже присутствует

Обратите внимание: если мы попробуем вставить, например, три элемента, но в процессе окажется, что второй элемент вставить нельзя, свертка && ... досрочно прекратит работать и оставшиеся элементы не будут добавлены:

std::set<int> my_set {1, 2, 3};

insert_all(my_set, 4, 2, 5); // Возвращает false

// теперь множество содержит значения {1, 2, 3, 4}, без 5!

Проверка попадания всех параметров в заданный диапазон

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

template <typename T, typename Ts>

bool within(T min, T max, Ts ts)

{

  return ((min <= ts && ts <= max) && ...);

}

Выражение (min <= ts && ts <= max) определяет, находится ли каждый элемент пакета параметров в диапазоне между min и max (включая min и max). Мы выбрали оператор &&, чтобы свести все результаты булева типа к одному, который имеет значение true только в том случае, если все отдельные результаты имеют такое же значение.

Это работает следующим образом:

within( 10, 20, 1, 15, 30);     // --> false

within( 10, 20, 11, 12, 13);    // --> true

within(5.0, 5.5, 5.1, 5.2, 5.3) // --> true

Что интересно: эта функция очень гибкая, поскольку единственным требованием, которое она предъявляет к типам, служит возможность сравнения экземпляров с помощью оператора <=. Это требование выполняется, например, типом std::string:

std::string aaa {"aaa"};

std::string bcd {"bcd"};

std::string def {"def"};

std::string zzz {"zzz"};

within(aaa, zzz, bcd, def); // --> true

within(aaa, def, bcd, zzz); // --> false

Отправка нескольких элементов в вектор

Кроме того, вы можете написать вспомогательную функцию, которая не обобщает никаких результатов, но обрабатывает несколько действий одного вида. Такими действиями могут быть вставки элементов в контейнер std::vector, поскольку они не возвращают никаких результатов (функция std::vector::insert() сообщает об ошибке, генерируя исключения):

template <typename T, typename ... Ts>

void insert_all(std::vector<T> &vec, Ts ... ts)

{

  (vec.push_back(ts), ...);

}

int main()

{

  std::vector<int> v {1, 2, 3};

  insert_all(v, 4, 5, 6);

}

Обратите внимание: мы используем оператор «запятая» (,), чтобы распаковать пакет параметров в отдельные вызовы vec.push_back(...), не выполняя свертку для самого результата. Эта функция также хорошо работает в отношении пустого пакета параметров, поскольку оператор «запятая» имеет неявный нейтральный элемент, void(), который означает «ничего не делать». 

Глава 2

Контейнеры STL

В этой главе:

□ использование идиомы erase-remove для контейнера std::vector;

□ удаление элементов из неотсортированного контейнера std::vector за время O(1);

□ получение доступа к экземплярам класса std::vector быстрым или безопасным способом;

□ поддержка экземпляров класса std::vector в отсортированном состоянии;

□ вставка элементов в контейнер std::map: эффективно и в соответствии с условиями;

□ исследование новой семантики подсказок для вставки элементов с помощью метода std::map::insert;

□ эффективное изменение ключей элементов std::map;

□ применение контейнера std::unordered_map для пользовательских типов;

□ отбор повторно встречающихся слов из пользовательского ввода и вывод их на экран в алфавитном порядке с помощью контейнера std::set;

□ реализация простого ОПН-калькулятора с использованием контейнера std::stack;

□ подсчет частоты встречаемости слов с применением контейнера std::map;

□ реализация вспомогательного инструмента для поиска очень длинных предложений в текстах с помощью std::multimap;

□ реализация личного списка текущих дел с помощью std::priority_queue.

Введение

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

1 ... 8 9 10 11 12 ... 121 ВПЕРЕД
Перейти на страницу:

Откройте для себя мир чтения на siteknig.com - месте, где каждая книга оживает прямо в браузере. Здесь вас уже ждёт произведение C++17 STL Стандартная библиотека шаблонов - Яцек Галовиц, относящееся к жанру Программирование. Никаких регистраций, никаких преград - только вы и история, доступная в полном формате. Наш литературный портал создан для тех, кто любит комфорт: хотите читать с телефона - пожалуйста; предпочитаете ноутбук - идеально! Все книги открываются моментально и представлены полностью, без сокращений и скрытых страниц. Каталог жанров поможет вам быстро найти что-то по настроению: увлекательный роман, динамичное фэнтези, глубокую классику или лёгкое чтение перед сном. Мы ежедневно расширяем библиотеку, добавляя новые произведения, чтобы вам всегда было что открыть "на потом". Сегодня на siteknig.com доступно более 200000 книг - и каждая готова стать вашей новой любимой. Просто выбирайте, открывайте и наслаждайтесь чтением там, где вам удобно.

Комментарии (0)