subrange
class (Standardowa biblioteka C++)
Udostępnia widok części elementów zakresu zgodnie z definicją iteratora rozpoczęcia i sentinel.
Składnia
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>>
Parametry szablonu
I
Typ iteratora rozpoczęcia. Koncepcja input_or_output_iterator
zapewnia iterator I
, który może odczytywać wszystkie elementy.
K
Rodzaj podgrupy: służy subrange_kind::sized
do określania podwojenia rozmiaru. Użyj sized_sentinel_for<S, I>
, jeśli iterator i sentinel można odjąć, aby uzyskać rozmiar. Wymaganie subrange_kind::sized || !sized_sentinel_for<S, I>
przechowuje rozmiar lokalnie w obiekcie podrzędnym i wymaga skonstruowania podloku przy użyciu konstruktora, który przyjmuje (dla którego określisz subrange_kind::sized
tutaj) lub za pomocą konstruktora, który przyjmuje sized_range
iterator
element , sentinel
i size
(więc należy określić sized_sentinel_for<S, I>
tutaj).
S
Typ iteratora końcowego. Koncepcja sized_sentinel_for
zapewnia, że S
może być używana jako sentynel i I
że można obliczyć odległość między elementy sentinel a bieżącą pozycją iteratora w I
stałym czasie.
Właściwości widoku
Opis poniższych wpisów można znaleźć w temacie View class characteristics (Wyświetlanie właściwości klas)
Characteristic | opis |
---|---|
Adapter zakresu | views::counted |
Zakres bazowy | Dowolny zakres |
Typ elementu | iter_reference_t<I> |
Wyświetl kategorię iteratora | Tak samo jak I kategoria s |
Wielkości | Jeśli K jest subrange::sized |
Jest const iterowalne |
Jeśli I można skopiować |
Wspólny zakres | Jeśli I i S są tego samego typu. |
Pożyczony zakres | Tak |
Elementy członkowskie
Funkcje składowe | Opis |
---|---|
KonstruktoryC++20 | Skonstruuj element subrange . |
operator PairLike C++20 |
subrange Przekonwertuj element na typ podobny do pary. |
advance C++20 |
Przenieś iterator na określoną odległość. |
begin |
Pobierz iterator do pierwszego elementu. |
empty C++20 |
Sprawdź, czy element subrange jest pusty. |
end C++20 |
Pobierz element sentinel na końcu obiektu subrange . |
next C++20 |
Tworzy kopię tego subrange obiektu, ale z zapisanym iteratorem przeniósł się do przodu określonej odległości. |
prev C++20 |
Tworzy kopię tego subrange obiektu, ale z zapisanym iteratorem przeniósł się z powrotem określoną odległość. |
size C++20 |
Pobierz liczbę elementów. |
Dziedziczone z view_interface |
Opis |
back C++20 |
Pobierz ostatni element. |
data C++20 |
Pobierz wskaźnik do pierwszego elementu. |
front C++20 |
Pobierz pierwszy element. |
operator[] C++20 |
Pobierz element na określonej pozycji. |
operator bool C++20 |
Sprawdź, czy element subrange jest pusty. |
Uwagi
Element jest subrange
przydatny w przypadku iteratora początku i końca, ale zamiast tego chcesz przekazać pojedynczy obiekt. Jeśli na przykład chcesz wywołać adapter zakresu, ale miał początek i zakończenie iteratorów, możesz użyć elementu , subrange
aby je owinąć i przekazać subrange
do adaptera zakresu.
Wymagania
Nagłówek: <ranges>
(od C++20)
Przestrzeń nazw: std::ranges
Opcja kompilatora: /std:c++20
lub nowsza jest wymagana.
Konstruktory
Utwórz element 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)
Parametry
begin
Iterator wskazujący pierwszy element w podgrupie.
end
Sentinel, która wskazuje na koniec podwojenia. Element, do który wskazuje, nie jest uwzględniony w podgrupie.
sizeHint
Rozmiar zakresu w elementach. Jest to używane do optymalizacji funkcji składowej size
i jest konieczne, jeśli chcesz utworzyć rozmiar subrange
z iteratora i sentinel, którego typy nie modelują sized_sentinel_for
.
Aby uzyskać informacje o typach parametrów szablonu, zobacz Parametry szablonu.
Wartość zwracana
subrange
Wystąpienie.
Uwagi
1) Domyślna konstrukcja przechowywanego iteratora i sentinel. Wskazówka rozmiaru jest ustawiona na 0.
2) Używa std::move()
metody , aby przenieść begin
iterator i end
sentinel do przechowywanego iteratora i sentynela.
3) Inicjuje przechowywany iterator za pomocą std::move(begin)
, przechowywanego sentynel z elementem std::move(end)
i wskazówkę rozmiaru przechowywanego z wartością size
, która powinna być równa odległości między pierwszym i drugim argumentem.
4) Konstruowanie elementu subrange
z zakresu.
5) Zachowanie nie jest zdefiniowane, jeśli szHint != ranges::distance(rg)
.
Adapter counted
zakresu może utworzyć subrange
element . Ten adapter przyjmuje iterator rozpoczęcia i liczbę.
Przykład: 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
Przekonwertuj element subrange
na typ, który modeluje pair-like
.
template<not-same-as<subrange> PairLike>
requires pair-like-convertible-from<PairLike, const I&, const S&>
constexpr operator PairLike() const;
Parametry
Brak.
Aby uzyskać informacje o typach parametrów szablonu, zobacz Parametry szablonu.
Wartość zwracana
PairLike
Wartość, która jest inicjowana bezpośrednio z przechowywanym iteratorem i sentinel.
Ostatnią wartością w parze będzie sentinel.
Pamiętaj, że element sentinel jest przeszłością ostatniego elementu w podrange, jak pokazano w poniższym przykładzie.
Uwagi
Ta konwersja jest przydatna w przypadku starszego Boost::Ranges
kodu, który akceptuje pary (pierwsze, ostatnie) w celu określenia zakresu.
Ta konwersja jest przydatna do konwertowania podgrupy na pair
typ lub tuple
lub inny, który modeluje pair_like
. Oto kilka przykładów pair_like
typów:
std::array<T, 2>
std::pair<T, U>
std::ranges::subrange<I, S, K>
std::tuple<T, U>
Przykład: 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
Dostosuj iterator dla tego subrange
elementu według n
elementów.
constexpr subrange& advance(const iter_difference_t<I> n);
Parametry
n
Ile elementów należy dostosować iterator. n
może być dodatni (ruch do przodu) lub, jeśli I
jest dwukierunkowy, ujemny (przesuń do tyłu).
Uwagi
Ta funkcja modyfikuje bieżący stan iteratora w elemencie subrange
.
Jeśli przechodzisz obok końca subrange
, iterator jest ustawiony na sentinel na końcu subrange
.
Jeśli przejdziesz obok początku subrange
elementu (przy użyciu wartości ujemnej n
), otrzymasz nieprawidłowy wyjątek parametru, jeśli zakres, z którego utworzono subrange
, nie ma elementu w miejscu.
Przykład: 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
Pobierz iterator do pierwszego elementu w pliku subrange
.
1) constexpr I begin() const requires copyable<I>;
2) [[nodiscard]] constexpr I begin() requires (!std::copyable<I>);
Parametry
Brak.
Wartość zwracana
Iterator wskazujący pierwszy element w elemecie subrange
.
Jeśli iterator nie jest kopiowalny, jest zwracany za pomocą polecenia std::move()
. Jeśli iterator zostanie przeniesiony, stan przechowywanego iteratora zależy od implementacji konstruktora przenoszenia dla elementu I
.
empty
Sprawdź, czy element subrange
jest pusty.
constexpr bool empty() const;
Parametry
Brak.
Wartość zwracana
Zwraca wartość true
, jeśli subrange
element nie zawiera żadnych elementów. W przeciwnym razie zwraca wartość false
.
end
Pobierz sentinel na końcu subrange
[[nodiscard]] constexpr S end() const;
Parametry
Brak.
Wartość zwracana
Sentinel, który jest zgodny z ostatnim elementem w pliku subrange
:
Sentinel jest skonstruowany z magazynu sentinel.
next
Tworzy kopię tego subrange
obiektu, ale z zapisanym iteratorem przeniósł się do przodu określonej odległości.
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) &&;
Parametry
n
Ile elementów ma przenieść iterator do przodu. Wartość domyślna to 1. Musi być dodatnia.
Wartość zwracana
Zwraca kopię elementu rozpoczynającego subrange
się od *n
*th.
Uwagi
W przeciwieństwie do advance()
elementu nie next()
zmienia lokalizacji iteratora przechowywanego w oryginalnym subrange
obiekcie .
Zwrócony subrange
element zawiera wszystkie elementy, które ma oryginalny podrange, ale iterator znajduje się w innej lokalizacji.
1) Wartość zwracana jest taka sama jak:
auto tmp = *this;
tmp.advance(n);
return tmp;
2) Wartość zwracana jest taka sama jak:
advance(n);
return std::move(*this);
Przykład: 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
Tworzy kopię tego subrange
obiektu , ale z zapisanym iteratorem przeniósł się z powrotem określoną odległość.
[[nodiscard]] constexpr subrange prev(std::iter_difference_t<I> n = 1 ) const
requires std::bidirectional_iterator<I>;
Parametry
n
Ile elementów ma przenieść iterator z powrotem. Wartość domyślna to 1. Musi być dodatnia.
Wartość zwracana
Zwraca kopię subrange
elementu , ale z iteratorem przeniesiono elementy wstecz n
.
Uwagi
W przeciwieństwie do advance()
elementu nie prev()
zmienia lokalizacji iteratora przechowywanego w oryginalnym subrange
obiekcie .
Zwrócony subrange
element zawiera wszystkie elementy, które ma oryginalny podrange, ale iterator znajduje się tylko w innej lokalizacji. Wartość zwracaną można traktować jako:
auto tmp = *this;
tmp.advance(-n);
return tmp;
Przykład: 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
Pobierz liczbę elementów w elemecie subrange
.
constexpr size() const
requires (K == ranges::subrange_kind::sized);
Parametry
Brak.
Wartość zwracana
Liczba elementów w elem.subrange
Jeśli rozmiar nie jest przechowywany, czyli w przypadku subrange
utworzenia obiektu z K == ranges::subrange_kind::sized
określonym i std::sized_sentinel_for<S, I>
nie jest spełniony, rozmiar jest zwracany jako odległość między iteratorami początkowymi i końcowymi.
Zmiana położenia iteratora begin
advance
, na przykład zmienia rozmiar zgłoszonego rozmiaru.