Снова здравствуйте. Перевод следующего материала подготовлен специально для студентов курса «Разработчик C++», занятия по которому стартуют уже 27 июня.
Библиотека Ranges была принята в C++20 на совещании стандартного комитета в Сан-Диего в ноябре прошлого года. Библиотека предоставляет компоненты для обработки диапазонов значений, направленных на упрощение нашего кода. К сожалению, библиотека Ranges не очень хорошо документирована, из-за этого ее труднее понять тем, кто хотел бы ее освоить. Этот пост предназначен для ознакомления с примерами кода, написанного с использованием Ranges и без нее.
Реализация библиотеки Ranges Эрика Ниблера доступна здесь. Она работает с Clang 3.6.2 или новее, gcc 5.2 или новее, и VC ++ 15.9 или новее. Примеры кода ниже были написаны и протестированы с последними версиями компиляторов. Стоит отметить, что эти примеры представляют собой типичные реализации и не обязательно являются единственными решениями, которые можно придумать.
Хотя стандартным пространством имен для библиотеки Ranges является
Следующие псевдонимы пространства имен используются в примерах ниже:
Также, для упрощения, мы будем ссылаться на следующие объекты, функции и лямбды:
АПДЕЙТ: Я хотел бы поблагодарить Эрика Ниблера и всех остальных, кто комментировал ниже, с предложениями для этих примеров кода. Я обновил несколько на основе их отзывов.
Вывести все элементы диапазона:
Выведите все элементы диапазона в обратном порядке:
Выведите только четные элементы диапазона, но в обратном порядке:
Пропустите первые два элемента диапазона и выведите только четные из следующих трех:
Выведите числа от 101 до 200:
Выведите все римские цифры от 101 до 200. Чтобы преобразовать число в соответствующее римское число, используется функция
Выведите римские цифры последних трех чисел, делимых на 7 в диапазоне [101, 200], в обратном порядке.
Создайте диапазон строк, содержащий римские цифры последних трех чисел, кратных 7 в диапазоне [101, 200], в обратном порядке.
Измените несортированный диапазон, чтобы он сохранял только уникальные значения, но в обратном порядке.
Удалите два наименьших и два самых больших значения диапазона и оставьте остальные, упорядоченные во втором диапазоне.
Объединить все строки в данном диапазоне в одно значение.
Подсчитайте количество слов (разделенных пробелом) в тексте.
Была ли статья полезной для вас? Пишите в комментарии.
Библиотека Ranges была принята в C++20 на совещании стандартного комитета в Сан-Диего в ноябре прошлого года. Библиотека предоставляет компоненты для обработки диапазонов значений, направленных на упрощение нашего кода. К сожалению, библиотека Ranges не очень хорошо документирована, из-за этого ее труднее понять тем, кто хотел бы ее освоить. Этот пост предназначен для ознакомления с примерами кода, написанного с использованием Ranges и без нее.
Реализация библиотеки Ranges Эрика Ниблера доступна здесь. Она работает с Clang 3.6.2 или новее, gcc 5.2 или новее, и VC ++ 15.9 или новее. Примеры кода ниже были написаны и протестированы с последними версиями компиляторов. Стоит отметить, что эти примеры представляют собой типичные реализации и не обязательно являются единственными решениями, которые можно придумать.
Хотя стандартным пространством имен для библиотеки Ranges является
std::ranges
, в данной текущей реализации библиотеки оно ranges::v3
.Следующие псевдонимы пространства имен используются в примерах ниже:
namespace rs = ranges::v3;
namespace rv = ranges::v3::view;
namespace ra = ranges::v3::action;
Также, для упрощения, мы будем ссылаться на следующие объекты, функции и лямбды:
std::string to_roman(int value)
{
std::vector<std::pair<int, char const*>> roman
{
{ 1000, "M" },{ 900, "CM" },
{ 500, "D" },{ 400, "CD" },
{ 100, "C" },{ 90, "XC" },
{ 50, "L" },{ 40, "XL" },
{ 10, "X" },{ 9, "IX" },
{ 5, "V" },{ 4, "IV" },
{ 1, "I" }
};
std::string result;
for (auto const & [d, r]: roman)
{
while (value >= d)
{
result += r;
value -= d;
}
}
return result;
}
std::vector<int> v{1,1,2,3,5,8,13,21,34};
auto print_elem = [](auto const e) {std::cout << e << '\n'; };
auto is_even = [](auto const i) {return i % 2 == 0; };
АПДЕЙТ: Я хотел бы поблагодарить Эрика Ниблера и всех остальных, кто комментировал ниже, с предложениями для этих примеров кода. Я обновил несколько на основе их отзывов.
Вывести все элементы диапазона:
До Ranges | После Ranges |
---|---|
С++ | С++ |
|
|
Выведите все элементы диапазона в обратном порядке:
До Ranges | После Ranges |
---|---|
С++ | С++ |
|
|
Выведите только четные элементы диапазона, но в обратном порядке:
До Ranges | После Ranges |
---|---|
С++ | С++ |
|
|
Пропустите первые два элемента диапазона и выведите только четные из следующих трех:
До Ranges | После Ranges |
---|---|
С++ | С++ |
|
|
Выведите числа от 101 до 200:
До Ranges | После Ranges |
---|---|
С++ | С++ |
|
|
Выведите все римские цифры от 101 до 200. Чтобы преобразовать число в соответствующее римское число, используется функция
to_roman()
, показанная выше.До Ranges | После Ranges |
---|---|
С++ | С++ |
|
|
Выведите римские цифры последних трех чисел, делимых на 7 в диапазоне [101, 200], в обратном порядке.
До Ranges | После Ranges |
---|---|
С++ | С++ |
|
|
Создайте диапазон строк, содержащий римские цифры последних трех чисел, кратных 7 в диапазоне [101, 200], в обратном порядке.
До Ranges | После Ranges |
---|---|
С++ | С++ |
|
|
Измените несортированный диапазон, чтобы он сохранял только уникальные значения, но в обратном порядке.
До Ranges | После Ranges |
---|---|
С++ | С++ |
|
|
Удалите два наименьших и два самых больших значения диапазона и оставьте остальные, упорядоченные во втором диапазоне.
До Ranges | После Ranges |
---|---|
С++ | С++ |
|
|
Объединить все строки в данном диапазоне в одно значение.
До Ranges | После Ranges |
---|---|
С++ | С++ |
|
|
Подсчитайте количество слов (разделенных пробелом) в тексте.
До Ranges | После Ranges |
---|---|
С++ | С++ |
|
|
Была ли статья полезной для вас? Пишите в комментарии.