Вспомогательная функция использует функцию std::count
из библиотеки STL. Она принимает три параметра: первые два представляют собой std::count
возвращает количество всех элементов внутри диапазона, равных третьему параметру.
В нашем выражении свертки мы всегда передаем в функцию std::count
Ее можно использовать следующим образом:
std::vector
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
bool insert_all(T &set, Ts ... ts)
{
return (set.insert(ts).second && ...);
}
Как же это работает? Функция insert
контейнера std::set
имеет следующую сигнатуру:
std::pair
Документация гласит, что при попытке вставить элемент функция insert
вернет пару из iterator
и переменной bool
. Если вставка пройдет успешно, значение переменной будет равно true
. Итератор же в этом случае укажет на
Наша вспомогательная функция после вставки обращается к полю .second
. Оно содержит переменную bool
, которая показывает, была ли вставка успешной. Если все полученные пары имеют значение true
, то все вставки прошли успешно. Свертка объединяет все результаты вставки с помощью оператора &&
и возвращает результат.
Контейнер можно использовать следующим образом:
std::set
insert_all(my_set, 4, 5, 6); // Возвращает true
insert_all(my_set, 7, 8, 2); // Возвращает false, поскольку 2 уже присутствует
Обратите внимание: если мы попробуем вставить, например, три элемента, но в процессе окажется, что второй элемент вставить нельзя, свертка && ...
досрочно прекратит работать и оставшиеся элементы не будут добавлены:
std::set
insert_all(my_set, 4, 2, 5); // Возвращает false
// теперь множество содержит значения {1, 2, 3, 4}, без 5!
Проверка попадания всех параметров в заданный диапазон
Поскольку можно убедиться, что одна из переменных находится в конкретном диапазоне, можно сделать то же самое для нескольких переменных с помощью выражений свертки:
template
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
: