subrange
class (стандартная библиотека C++)
Предоставляет представление части элементов диапазона, определенных начальным итератором и sentinel.
Синтаксис
template<input_or_output_iterator I, sentinel_for<I> S, subrange_kind K>
requires (K == subrange_kind::sized || !sized_sentinel_for<S, I>)
class subrange : public view_interface<subrange<I, S, K>>
Параметры шаблона
I
Тип итератора начала. Концепция input_or_output_iterator
гарантирует, что I
это итератор, который может считывать все элементы.
K
Тип подранга: используется subrange_kind::sized
для указания подранга размера. Используйте, sized_sentinel_for<S, I>
если итератор и sentinel можно вычитать для получения размера. Требование subrange_kind::sized || !sized_sentinel_for<S, I>
сохраняет размер локально в объекте subrange и требует создания подранга либо с помощью конструктора, принимающего ( sized_range
для которого вы указали subrange_kind::sized
здесь), либо через конструктор, iterator
принимающий объект , sentinel
и size
(поэтому вы указали sized_sentinel_for<S, I>
здесь).
S
Тип итератора конца. Концепция sized_sentinel_for
гарантирует, что S
можно использовать в качестве sentinel и I
что можно вычислить расстояние между sentinel и текущим положением итератора в постоянном I
времени.
Просмотр характеристик
Описание следующих записей см. в разделе "Просмотр характеристик класса"
Characteristic | Description |
---|---|
Адаптер диапазона | views::counted |
Базовый диапазон | Любой диапазон |
Тип элемента | iter_reference_t<I> |
Просмотр категории итератора | То же, что I и категория s |
Размер | Если K имеет значение subrange::sized |
Is const -iterable |
Если I можно скопировать |
Общий диапазон | Если I и S один и тот же тип. |
Заимствуемый диапазон | Да |
Участники
Функции-члены | Description |
---|---|
КонструкторыC++20 | Создайте subrange |
operator PairLike C++20 |
subrange Преобразуйте тип, похожий на пару. |
advance C++20 |
Перемещение итератора заданного расстояния. |
begin |
Получите итератор к первому элементу. |
empty C++20 |
Проверьте, является ли пустой subrange . |
end C++20 |
Получите sentinel в конце subrange . |
next C++20 |
Создает копию этого subrange , но с хранимым итератором перемещается вперед указанное расстояние. |
prev C++20 |
Создает копию этого subrange , но с сохраненным итератором перемещается обратно указанное расстояние. |
size C++20 |
Получение количества элементов. |
Наследуется от view_interface |
Description |
back C++20 |
Получите последний элемент. |
data C++20 |
Получите указатель на первый элемент. |
front C++20 |
Получите первый элемент. |
operator[] C++20 |
Получите элемент в указанной позиции. |
operator bool C++20 |
Проверьте, является ли пустой subrange . |
Замечания
Это subrange
полезно, если у вас есть итератор начала и конца, но вы хотите передать один объект. Например, если вы хотите вызвать адаптер диапазона, но имел начальный и конечный итератор, можно использовать subrange
для их упаковки и передачи subrange
адаптеру диапазона.
Требования
Заголовок: <ranges>
(с C++20)
Пространство имен: std::ranges
Параметр компилятора: /std:c++20
или более поздней версии требуется.
Конструкторы
Создайте subrange
.
1) subrange() requires default_initializable<I> = default;
2) template <Convertible_to_non_slicing<I> It>
constexpr subrange(It begin, S end) requires (!Store_size);
3) template <Convertible_to_non_slicing<I> It>
constexpr subrange(It begin, S end, const Size_type size) requires (K == subrange_kind::sized);
4) template <Not_same_as<subrange> rg>
requires borrowed_range<rg>
&& Convertible_to_non_slicing<iterator_t<rg>, I>
&& convertible_to<sentinel_t<rg>, S>
constexpr subrange(rg&& r) requires (!_Store_size || sized_range<rg>);
5) template <borrowed_range rg>
requires Convertible_to_non_slicing<iterator_t<rg>, I> && convertible_to<sentinel_t<rg>, S>
constexpr subrange(rg&& r, const _Size_type sizeHint) requires (K == subrange_kind::sized)
Параметры
begin
Итератор, указывающий на первый элемент в подранге.
end
Sentinel, указывающий на конец подранга. Элемент, на который он указывает, не входит в подранг.
sizeHint
Размер диапазона в элементах. Это используется для оптимизации size
функции-члена и требуется, если вы хотите сделать размер subrange
из итератора и sentinel, типы которых не моделировать sized_sentinel_for
.
Сведения о типах параметров шаблона см. в разделе "Параметры шаблона".
Возвращаемое значение
Экземпляр класса subrange
.
Замечания
1) По умолчанию создает хранимый итератор и sentinel. Указание размера имеет значение 0.
2) Используется std::move()
для перемещения begin
итератора и end
sentinel в сохраненный итератор и sentinel.
3) Инициализирует хранимый итератор с std::move(begin)
, сохраненный sentinel с std::move(end)
указанием размера и указанием size
хранящегося размера, с которым должно быть равно расстояние между первым и вторым аргументами.
4) Создание subrange
из диапазона.
5) Поведение не определено, если szHint != ranges::distance(rg)
.
Адаптер counted
диапазона может создать subrange
. Этот адаптер принимает итератор начала и счетчика.
Пример: counted
// requires /std:c++20 or later
#include <ranges>
#include <iostream>
#include <vector>
int main()
{
std::vector<int> v{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
auto pos5 = std::ranges::find(v, 5);
auto countedView = std::views::counted(pos5, 5);
for (auto e : countedView) // outputs 5 6 7 8 9
{
std::cout << e << ' ';
}
std::cout << '\n';
// You can pass the range directly if it supports input_or_output_iterator, in which case, the
// count starts from the first element
const char chars[] = { 'H','i',' ','t','h','e','r','e' };
for (char c : std::views::counted(chars, 2))
{
std::cout << c; // outputs Hi
}
}
5 6 7 8 9
Hi
operator PairLike
Преобразуйте тип subrange
, который моделирует pair-like
.
template<not-same-as<subrange> PairLike>
requires pair-like-convertible-from<PairLike, const I&, const S&>
constexpr operator PairLike() const;
Параметры
Нет.
Сведения о типах параметров шаблона см. в разделе "Параметры шаблона".
Возвращаемое значение
Значение PairLike
, которое инициализировано напрямую с помощью хранимого итератора и sentinel.
Последнее значение в паре будет sentinel.
Помните, что sentinel находится за последним элементом в подранге, как показано в приведенном ниже примере.
Замечания
Это преобразование полезно с более старым Boost::Ranges
кодом, который принимает пары (первый, последний) для обозначения диапазона.
Это преобразование полезно для преобразования подранга в или pair
tuple
другой тип, который моделирует pair_like
. Ниже приведены некоторые примеры pair_like
типов:
std::array<T, 2>
std::pair<T, U>
std::ranges::subrange<I, S, K>
std::tuple<T, U>
Пример: operator PairLike()
// requires /std:c++20 or later
#include <iostream>
#include <ranges>
#include <vector>
#include <utility>
int main()
{
constexpr int a[] = {0, 1, 2, 3, 4, 5};
std::ranges::subrange rg(a);
rg.advance(2);
const std::pair<const int*, const int*> p = rg;
for (auto e : rg)
{
std::cout << e << ' ';
}
// because the sentinel points after the last element, subtract one to get the last element
std::cout << '\n' << *p.first << ':' << *(p.second - 1) << '\n'; // outputs 2:5
}
2 3 4 5
2:5
advance
Настройте итератор для этого subrange
по n
элементам.
constexpr subrange& advance(const iter_difference_t<I> n);
Параметры
n
Сколько элементов для настройки итератора. n
может быть положительным (перемещение вперед) или, если I
это двунаправленный, отрицательный (перемещение назад).
Замечания
Эта функция изменяет текущее состояние итератора в .subrange
Если вы переходите к концу subrange
, итератор устанавливается в sentinel в конце subrange
.
Если вы перейдете к началу subrange
(используя отрицательный n
), вы получите недопустимое исключение параметров, если диапазон subrange
, сделанный из, не имеет элемента в месте.
Пример: advance
.
// requires /std:c++20 or later
#include <iostream>
#include <ranges>
#include <string>
#include <vector>
void print(const std::string &msg, auto &&v)
{
std::cout << msg << '\n';
for (auto& x : v)
{
std::cout << x << ' ';
}
std::cout << '\n';
}
int main()
{
std::vector v = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
print("Original vector: ", v); // outputs 0 1 2 3 4 5 6 7 8 9 10
// create a subrange 3 4 5 6
std::ranges::subrange theSubrange{ std::ranges::find(v,3), std::ranges::find(v, 7) };
print("The subrange: ", theSubrange); // outputs 3 4 5 6
auto sr = theSubrange.advance(2); // get a subrange 2 positions to the right of the current iterator location
print("theSubrange.advance(2): ", sr); // outputs 5 6
print("Note that subrange's iterator moved during advance(): ", sr); // outputs 5 6
sr = theSubrange.advance(-3); // Moving before the subrange, but onto a valid element in the original range
print("theSubrange.advance(-3): ", sr); // outputs 2 3 4 5 6
}
Original vector:
0 1 2 3 4 5 6 7 8 9 10
The subrange:
3 4 5 6
theSubrange.advance(2):
5 6
Note that subrange's iterator moved during advance():
5 6
theSubrange.advance(-3):
2 3 4 5 6
begin
Получите итератор к первому элементу в элементе subrange
.
1) constexpr I begin() const requires copyable<I>;
2) [[nodiscard]] constexpr I begin() requires (!std::copyable<I>);
Параметры
Нет.
Возвращаемое значение
Итератор, указывающий на первый элемент в элементе subrange
.
Если итератор не копируется, он возвращается с std::move()
. При перемещении итератора состояние хранимого итератора зависит от реализации конструктора перемещения для I
.
empty
Проверьте, является ли пустой subrange
.
constexpr bool empty() const;
Параметры
Нет.
Возвращаемое значение
Возвращает, true
если subrange
элементы отсутствуют. В противном случае возвращается false
.
end
Получение sentinel в конце subrange
[[nodiscard]] constexpr S end() const;
Параметры
Нет.
Возвращаемое значение
Sentinel, следующий за последним элементом subrange
в :
Sentinel создается копией из хранимого sentinel.
next
Создает копию этого subrange
, но с хранимым итератором перемещается вперед указанное расстояние.
1) [[nodiscard]] constexpr subrange next(iter_difference_t<I> n = 1) const & requires forward_iterator<I>;
2) [[nodiscard]] constexpr subrange next(iter_difference_t<I> n = 1) &&;
Параметры
n
Сколько элементов для перемещения итератора вперед. По умолчанию равен 1. Должно быть положительным.
Возвращаемое значение
Возвращает копию начального subrange
элемента *n
*th.
Замечания
В отличие от advance()
этого, next()
не изменяет расположение итератора, хранящегося в исходном файле subrange
.
Возвращенный subrange
элемент содержит все элементы, которые имеет исходный подранг, но итератор находится в другом расположении.
1) Возвращаемое значение совпадает с:
auto tmp = *this;
tmp.advance(n);
return tmp;
2) Возвращаемое значение совпадает с:
advance(n);
return std::move(*this);
Пример: next
// requires /std:c++20 or later
#include <iostream>
#include <ranges>
#include <string>
#include <vector>
void print(const std::string &msg, auto &&v)
{
std::cout << msg << '\n';
for (auto& x : v)
{
std::cout << x << ' ';
}
std::cout << '\n';
}
int main()
{
std::vector v = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
print("Original vector:", v); // 0 1 2 3 4 5 6 7 8 9 10
// create a subrange from the front of v up to (but not including) the element 7
std::ranges::subrange theSubrange{ std::ranges::find(v,1), std::ranges::find(v, 7) };
print("The subrange:", theSubrange); // 1 2 3 4 5 6
auto forward = theSubrange.advance(3); // get a subrange 3 positions to the right of the current iterator location
print("theSubrange.advance(3):", forward); // 4 5 6
// prev()
auto previous = theSubrange.prev(2); // move back 2
print("theSubrange.prev(2):", previous); // 2 3 4 5 6
print("Note that the subrange's iterator did *not* move during prev():", theSubrange); // 4 5 6
}
Original vector:
0 1 2 3 4 5 6 7 8 9 10
The subrange:
1 2 3 4 5 6
theSubrange.next(3):
4 5 6
Note that the original subrange's iterator did *not* move during next():
1 2 3 4 5 6
prev
Создает копию этого subrange
элемента, но с сохраненным итератором перемещается обратно указанное расстояние.
[[nodiscard]] constexpr subrange prev(std::iter_difference_t<I> n = 1 ) const
requires std::bidirectional_iterator<I>;
Параметры
n
Сколько элементов для перемещения итератора обратно. По умолчанию равен 1. Должно быть положительным.
Возвращаемое значение
Возвращает копию subrange
элемента, но с итератором перемещены обратно n
.
Замечания
В отличие от advance()
этого, prev()
не изменяет расположение итератора, хранящегося в исходном файле subrange
.
Возвращенный subrange
элемент содержит все элементы, которые имеет исходный подранг, но итератор находится только в другом расположении. Возвращаемое значение можно рассматривать следующим образом:
auto tmp = *this;
tmp.advance(-n);
return tmp;
Пример: prev
.
// requires /std:c++20 or later
#include <iostream>
#include <ranges>
#include <string>
#include <vector>
void print(const std::string &msg, auto &&v)
{
std::cout << msg << '\n';
for (auto& x : v)
{
std::cout << x << ' ';
}
std::cout << '\n';
}
int main()
{
std::vector v = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
print("Original vector:", v); // 0 1 2 3 4 5 6 7 8 9 10
// create a subrange from the front of v up to (but not including) the element 7
std::ranges::subrange theSubrange{std::ranges::find(v,1), std::ranges::find(v, 7)};
print("The subrange: ", theSubrange); // 1 2 3 4 5 6
auto forward = theSubrange.advance(3); // get a subrange 3 positions to the right of the current iterator location
print("theSubrange.advance(3):", forward); // 4 5 6
// prev()
auto previous = theSubrange.prev(2); // move back 2
print("theSubrange.prev(2):", previous); // 2 3 4 5 6
print("Note that the subrange's iterator did *not* move during prev():", theSubrange); // 4 5 6
}
Original vector:
0 1 2 3 4 5 6 7 8 9 10
The subrange:
1 2 3 4 5 6
theSubrange.advance(3):
4 5 6
theSubrange.prev(2):
2 3 4 5 6
Note that the subrange's iterator did *not* move during prev():
4 5 6
size
Получение количества элементов в элементе subrange
.
constexpr size() const
requires (K == ranges::subrange_kind::sized);
Параметры
Нет.
Возвращаемое значение
Число элементов в массиве subrange
.
Если размер не хранится, то это происходит при subrange
создании с K == ranges::subrange_kind::sized
указанным и std::sized_sentinel_for<S, I>
не удовлетворенным размером, то размер возвращается в качестве расстояния между начальным и конечным итераторами.
Изменение положения begin
итератора, advance
например изменение размера сообщаемого размера.