- Фантастика и фэнтези
- Ироническое фэнтези
- Стимпанк
- Детективная фантастика
- Киберпанк
- Попаданцы
- LitRPG
- Космоопера
- Технофэнтези
- Городская фантастика
- Русское фэнтези
- Юмористическая фантастика
- Космическая фантастика
- Боевое фэнтези
- Эпическая фантастика
- Зарубежная фантастика
- Книги магов
- Мистика
- Разная фантастика
- Разное фэнтези
- Любовное фэнтези
- Романтическая фантастика
- Городское фентези
- Историческая фантастика
- Историческое фэнтези
- Социально-философская фантастика
- Сказочная фантастика
- Иностранное фэнтези
- Романтическое фэнтези
- Ироническая фантастика
- Ужасы и Мистика
- Постапокалипсис
- Героическая фантастика
- Фэнтези
- Научная Фантастика
- Социально-психологическая
- Альтернативная история
- Боевая фантастика
- Разная литература
- Пословицы, поговорки
- Шахматы
- Визуальные искусства
- Фанфик
- Авто и ПДД
- Военное
- Отраслевые издания
- Гиды, путеводители
- Зарубежная образовательная литература
- Военная история
- Цитаты из афоризмов
- Современная литература
- Великолепные истории
- Начинающие авторы
- Современная зарубежная литература
- Боевые искусства
- Изобразительное искусство, фотография
- Кино
- Литература 19 века
- Недвижимость
- Музыка, музыканты
- Готические новеллы
- Истории из жизни
- Культура и искусство
- Спецслужбы
- Зарубежная прикладная литература
- Музыка, танцы
- Подростковая литература
- Прочее
- Военная техника, оружие
- Газеты и журналы
- Периодические издания
- Домоводство, Дом и семья
- Любовные романы
- Экономическая литература
- Научные и научно-популярные книги
- О животных
- Биохимия
- Культурология
- Юриспруденция
- Политика
- Психотерапия
- Языкознание
- Научпоп
- Медицина
- Психология, личное
- Радиотехника
- Филология
- Педагогика
- Образовательная литература
- Деловая литература
- Физика
- Науки: разное
- Химия
- Воспитание детей, педагогика
- Детская психология
- Зарубежная публицистика
- Биология
- Архитектура
- Зарубежная психология
- Науки о космосе
- Социология
- Математика
- География
- Беременность, ожидание детей
- Литературоведение
- Транспорт, военная техника
- Обществознание
- Зоология
- География
- Альтернативная медицина
- Иностранные языки
- Ветеринария
- Рефераты
- Астрология
- Биофизика
- Экология
- История Европы
- Учебники
- Шпаргалки
- Государство и право
- Ботаника
- Религиоведение
- История
- Техническая литература
- Прочая научная литература
- Психология
- Детективы и Триллеры
- Справочная литература
- Проза
- Новелла
- Юмор
- Проза
- Историческая проза
- Русская современная проза
- Советская классическая проза
- Повести
- Очерки
- Эссе
- Рассказы
- Зарубежная современная проза
- Сентиментальная проза
- Зарубежная классика
- Афоризмы
- Эпистолярная проза
- Феерия
- Семейный роман/Семейная сага
- Разное
- Антисоветская литература
- Магический реализм
- Русская классическая проза
- Современная проза
- О войне
- Контркультура
- Классическая проза
- Поэзия, Драматургия
- Детская литература
- Детская фантастика
- Детские остросюжетные
- Детские стихи
- Детские приключения
- Внеклассное чтение
- Учебная литература
- Зарубежные детские книги
- Бизнес
- Загадки
- Книги для подростков
- Школьные учебники
- Детский фольклор
- Книги для дошкольников
- Детские детективы
- Детская познавательная и развивающая литература
- Буквари
- Прочая детская литература
- Сказка
- Детская проза
- Детская образовательная литература
- Юмор
- Документальные книги
- Бизнес
- Внешнеэкономическая деятельность
- Тайм-менеджмент
- Кадровый менеджмент
- О бизнесе популярно
- Управление, подбор персонала
- Бизнес
- Менеджмент и кадры
- Продажи
- Экономика
- Ценные бумаги и инвестиции
- Малый бизнес
- Делопроизводство, офис
- Корпоративная культура, бизнес
- Банковское дело
- Финансы
- Зарубежная деловая литература
- Ораторское искусство / риторика
- Личные финансы
- Интернет-бизнес
- Поиск работы
- Государственное и муниципальное управление
- Бухучет и аудит
- Работа с клиентами
- Менеджмент
- Краткое содержание
- Личная эффективность
- Переговоры
- Приключения
- Старинная литература
- Религия и духовность
- Компьютеры и Интернет
- Блог
Читаем без скачивания C++17 STL Стандартная библиотека шаблонов - Яцек Галовиц
Шрифт:
Интервал:
Закладка:
}
static bool ends_with_b (const std::string &s)
{
return s.rfind("b") == s.length() - 1;
}
3. Теперь реализуем вспомогательную функцию и назовем ее combine. Она принимает бинарную функцию в качестве первого параметра — это может быть, например, логическое И либо логическое ИЛИ. Затем она принимает два других параметра, представляющих собой две функции-предиката, которые нужно объединить:
template <typename A, typename B, typename F>
auto combine(F binary_func, A a, B b)
{
4. Просто возвращаем лямбда-выражение, которое захватывает новую комбинацию предикатов. Оно направляет параметр обоим предикатам, а затем помещает результаты работы их обоих в бинарную функцию и возвращает ее результат:
return [=](auto param) {
return binary_func(a(param), b(param));
};
}
5. Укажем, что будем использовать пространство имен std с целью сэкономить немного времени при написании функции main:
using namespace std;
6. Теперь объединим две функции-предиката в другую функцию-предикат, говорящую, начинается ли заданная строка с символа a и заканчивается ли символом b, как, например, строки "ab" или "axxxb". На роль бинарной функции выбираем std::logical_and. Это шаблонный класс, экземпляр которого нужно создавать, вследствие чего будем использовать его вместе с фигурными скобками. Обратите внимание: мы не предоставляем дополнительный параметр шаблона, поскольку для данного класса он по умолчанию будет равен void. Эта специализация класса самостоятельно выводит все типы параметров:
int main()
{
auto a_xxx_b (combine(
logical_and<>{},
begins_with_a, ends_with_b));
7. Итерируем по стандартному потоку ввода и выводим на экран все слова, которые удовлетворяют условиям предиката:
copy_if(istream_iterator<string>{cin}, {},
ostream_iterator<string>{cout, ", "},
a_xxx_b);
cout << 'n';
}
8. Компиляция и запуск программы дадут следующий результат. Мы передаем программе четыре слова, но только два из них удовлетворяют условиям предиката:
$ echo "ac cb ab axxxb" | ./combine
ab, axxxb,
Дополнительная информация
Библиотека STL уже предоставляет несколько функциональных объектов наподобие std::logical_and, std::logical_or, а также множество других, поэтому не нужно реализовывать их в каждом проекте. Ознакомиться со справочным материалом по С++ и исследовать доступные варианты можно на http://en.cppreference.com/w/cpp/utility/functional.
Вызываем несколько функций с одинаковыми входными данными
Существует множество задач, чьи решения требуют написания повторяющегося кода. Большую его часть можно легко заменить лямбда-выражениями, и очень просто создать вспомогательную функцию, которая будет оборачивать подобные повторяющиеся задачи.
В данном разделе мы поработаем с лямбда-выражениями, чтобы направить один вызов функции со всеми его параметрами нескольким получателям. Мы сделаем это, не задействовав никаких дополнительных структур данных, так что перед компилятором будет стоять простая задача: сгенерировать бинарный файл без лишних затрат.
Как это делается
В этом примере мы напишем вспомогательную функцию для работы с лямбда-выражениями, которая направляет один вызов нескольким объектам, и еще одну такую функцию, направляющую один вызов нескольким функциям. Эту комбинацию мы используем в нашем примере, чтобы вывести на экран одно сообщение с помощью разных функций-принтеров.
1. Включим заголовочный файл, необходимый для вывода данных на экран:
#include <iostream>
2. Сначала реализуем функцию multicall, которая является основной для этого примера. Она принимает произвольное количество функций в качестве параметров и возвращает лямбда-выражение, принимающее один параметр. Она перенаправляет данный параметр всем функциям, предоставленным ранее. Таким образом, можно определить функцию auto call_all(multicall(f,g,h)), а затем вызов call_all(123) приведет к серии вызовов f(123); g(123); h(123);. Эта функция уже выглядит сложной, поскольку требуется распаковать набор параметров, в котором находятся функции, в набор вызовов с помощью конструктора std::initializer_list.
static auto multicall (auto ...functions)
{
return [=](auto x) {
(void)std::initializer_list<int>{
((void)functions(x), 0)...
};
};
}
3. Следующая вспомогательная функция принимает функцию f и набор параметров xs. После этого она вызывает функцию f для каждого из параметров. Таким образом, вызов for_each(f,1,2,3) приводит к серии вызовов: f(1); f(2); f(3);. Функция, по сути, использует такой же синтаксический прием для распаковки набора параметров xs в набор вызовов функций, как и функция, показанная ранее.
static auto for_each (auto f, auto ...xs) {
(void)std::initializer_list<int>{
((void)f(xs), 0)...
};
}
4. Функция brace_print принимает два символа и возвращает новый объект функции, принимающий один параметр x. Она выводит его на экран, окружив двумя символами, которые мы только что захватили.
static auto brace_print (char a, char b) {
return [=] (auto x) {
std::cout << a << x << b << ", ";
};
}
5. Теперь наконец можно использовать все эти функции в функции main. Сначала определим функции f, g и h. Они представляют функции print, которые принимают значения и выводят их на экран, окружив разными скобками. Функция nl принимает любой параметр и просто выводит на экран символ переноса строки.
int main()
{
auto f (brace_print('(', ')'));
auto g (brace_print('[', ']'));
auto h (brace_print('{', '}'));
auto nl ([](auto) { std::cout << 'n'; });
6. Объединим все эти функции с помощью вспомогательной функции multicall:
auto call_fgh (multicall(f, g, h, nl));
7. Мы хотим, чтобы каждое предоставленное нами число было выведено на экран трижды в разных скобках. Таким образом, нужно выполнить один вызов функции, который приведет к пяти вызовам нашей мультифункции, а та, в свою очередь, выполнит четыре вызова для функций f, g, h и nl:
for_each(call_fgh, 1, 2, 3, 4, 5);
}
8. Перед компиляцией и запуском программы подумаем, какой результат должны получить:
$ ./multicaller
(1), [1], {1},
(2), [2], {2},
(3), [3], {3},
(4), [4], {4},
(5), [5], {5},
Как это работает
Вспомогательные функции, которые мы только что реализовали, выглядят очень сложными. Так произошло из-за распаковки набора параметров с помощью std::initializer_list. Почему мы вообще использовали эту структуру данных? Еще раз взглянем на for_each:
auto for_each ([](auto f, auto