subrange
class (standardní knihovna jazyka C++)
Poskytuje zobrazení části prvků rozsahu definovaného počátečním iterátorem a sentinelem.
Syntaxe
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 šablony
I
Typ počátečního iterátoru. Koncept input_or_output_iterator
zajišťuje, že I
je iterátor, který může číst všechny prvky.
K
Druh poduspořádku: Slouží subrange_kind::sized
k určení poduspořádku velikosti. Použijte sized_sentinel_for<S, I>
, pokud je možné iterátor a sentinel odečíst a získat tak velikost. Požadavek subrange_kind::sized || !sized_sentinel_for<S, I>
ukládá velikost místně v objektu podsložky a vyžaduje, abyste vytvořili poduspořádku buď pomocí konstruktoru, který vezme sized_range
(pro který byste zde určili subrange_kind::sized
) nebo prostřednictvím konstruktoru iterator
, který přebírá objekt , sentinel
a size
(tak byste zde zadali sized_sentinel_for<S, I>
).
S
Typ koncového iterátoru. Koncept sized_sentinel_for
zajišťuje, že S
se dá použít jako sentinel I
a že je možné vypočítat vzdálenost mezi sentinelem a aktuálním umístěním iterátoru v I
konstantním čase.
Zobrazení charakteristik
Popis následujících položek naleznete v tématu Zobrazení vlastností třídy.
Charakteristika | Popis |
---|---|
Adaptér rozsahu | views::counted |
Podkladová oblast | Libovolný rozsah |
Typ elementu | iter_reference_t<I> |
Zobrazit kategorii iterátoru | Stejné jako I kategorie s |
Tříděný | Pokud K je subrange::sized |
Je const -iterable |
Pokud I je možné kopírovat |
Společný rozsah | Pokud I a S jsou stejného typu. |
Zapůjčený rozsah | Ano |
Členové
Členské funkce | Popis |
---|---|
KonstruktoryC++20 | Vytvoření .subrange |
operator PairLike C++20 |
subrange Převeďte typ podobný páru. |
advance C++20 |
Přesuňte iterátor o zadanou vzdálenost. |
begin |
Získejte iterátor k prvnímu prvku. |
empty C++20 |
Otestujte, jestli subrange je prázdný. |
end C++20 |
Získejte sentinel na konci subrange . |
next C++20 |
Vytvoří kopii tohoto subrange objektu, ale s uloženým iterátorem se posune o zadanou vzdálenost. |
prev C++20 |
Vytvoří kopii tohoto subrange objektu, ale s uloženým iterátorem se přesune zpět za zadanou vzdálenost. |
size C++20 |
Získá počet prvků. |
Zděděno z view_interface |
Popis |
back C++20 |
Získejte poslední prvek. |
data C++20 |
Získejte ukazatel na první prvek. |
front C++20 |
Získejte první prvek. |
operator[] C++20 |
Získejte prvek na zadané pozici. |
operator bool C++20 |
Otestujte, jestli subrange je prázdný. |
Poznámky
Je subrange
užitečné, když máte počáteční a koncový iterátor, ale chcete místo toho předat jeden objekt. Pokud byste například chtěli zavolat adaptér rozsahu, ale měli počáteční a koncové iterátory, mohli byste je použít subrange
k jejich zabalení a předání subrange
adaptéru rozsahu.
Požadavky
Hlavička: <ranges>
(od C++20)
Obor názvů: std::ranges
Je vyžadována možnost kompilátoru: /std:c++20
nebo novější.
Konstruktory
Vytvoření souboru 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
Iterátor, který odkazuje na první prvek v poduspořádce.
end
Sentinel, který odkazuje na konec poduspořádku. Prvek, na který odkazuje, není zahrnut v poduspořádku.
sizeHint
Velikost rozsahu v elementech. Používá se k optimalizaci size
členské funkce a je potřeba, pokud chcete vytvořit velikost subrange
iterátoru a sentinelu, jehož typy model nemají sized_sentinel_for
.
Informace o typech parametrů šablony naleznete v tématu Parametry šablony.
Vrácená hodnota
Instance subrange
.
Poznámky
1) Výchozí vytvoří uložený iterátor a sentinel. Nápověda velikosti je nastavená na 0.
2) Používá std::move()
k přesunutí iterátoru begin
a end
sentinelu do uloženého iterátoru a sentinelu.
3) Inicializuje uložený iterátor s std::move(begin)
uloženým sentinelem std::move(end)
a nápovědu k uložené velikosti s size
, která by se měla rovnat vzdálenosti mezi prvním a druhým argumentem.
4) Vytvořte z rozsahu subrange
.
5) Chování není definováno, pokud szHint != ranges::distance(rg)
.
Adaptér counted
rozsahu subrange
může vytvořit . Tento adaptér má počáteční iterátor a počet.
Příklad: 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
Převeďte typ subrange
, který modeluje pair-like
.
template<not-same-as<subrange> PairLike>
requires pair-like-convertible-from<PairLike, const I&, const S&>
constexpr operator PairLike() const;
Parametry
Žádná
Informace o typech parametrů šablony naleznete v tématu Parametry šablony.
Vrácená hodnota
Hodnota PairLike
, která je přímo inicializována uloženým iterátorem a sentinelem.
Poslední hodnotou v páru bude sentinel.
Mějte na paměti, že sentinel je za posledním prvkem v poduspořádku, jak je znázorněno v následujícím příkladu.
Poznámky
Tento převod je užitečný u staršího Boost::Ranges
kódu, který přijímá páry (první, poslední) k označení rozsahu.
Tento převod je užitečný pro převod dílčího uspořádání na pair
nebo tuple
jiný typ, který modeluje pair_like
. Mezi příklady typů pair_like
patří:
std::array<T, 2>
std::pair<T, U>
std::ranges::subrange<I, S, K>
std::tuple<T, U>
Příklad: 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
Upravte iterátor pro tento subrange
prvek prvky n
.
constexpr subrange& advance(const iter_difference_t<I> n);
Parametry
n
Kolik prvků má iterátor upravit. n
může být pozitivní (posun vpřed) nebo , pokud I
je obousměrný, záporný (posun dozadu).
Poznámky
Tato funkce upraví aktuální stav iterátoru v objektu subrange
.
Pokud přejdete na konec subrange
, iterátor se nastaví na sentinel na konci subrange
.
Pokud přejdete na začátek (pomocí záporné n
hodnoty subrange
), získáte neplatnou výjimku parametru, pokud oblast, ze které jste provedlisubrange
, nemá prvek na místě.
Příklad: 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
Získejte iterátor na první prvek v objektu subrange
.
1) constexpr I begin() const requires copyable<I>;
2) [[nodiscard]] constexpr I begin() requires (!std::copyable<I>);
Parametry
Žádná
Vrácená hodnota
Iterátor ukazující na první prvek v objektu subrange
.
Pokud iterátor není možné kopírovat, vrátí se příkazem std::move()
. Pokud se iterátor přesune, stav uloženého iterátoru závisí na implementaci konstruktoru přesunutí pro I
.
empty
Otestujte, jestli subrange
je prázdný.
constexpr bool empty() const;
Parametry
Žádná
Vrácená hodnota
Vrátí true
, pokud neobsahuje subrange
žádné prvky. V opačném případě vrátí hodnotu false
.
end
Získání sentinelu na konci subrange
[[nodiscard]] constexpr S end() const;
Parametry
Žádná
Vrácená hodnota
Sentinel, který následuje za posledním prvkem v :subrange
Sentinel je vytvořený kopírováním z uloženého sentinelu.
next
Vytvoří kopii tohoto subrange
objektu, ale s uloženým iterátorem se posune o zadanou vzdálenost.
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
Kolik prvků se má iterátor přesunout dopředu. Výchozí hodnota je 1. Musí být pozitivní.
Vrácená hodnota
Vrátí kopii počátečního subrange
prvku *n
*th.
Poznámky
Na rozdíl od advance()
, next()
nezmění umístění iterátoru uloženého v původním subrange
souboru .
subrange
Vrácená položka obsahuje všechny prvky, které má původní dílčí uspořádání, ale iterátor je v jiném umístění.
1) Vrácená hodnota je stejná jako:
auto tmp = *this;
tmp.advance(n);
return tmp;
2) Vrácená hodnota je stejná jako:
advance(n);
return std::move(*this);
Příklad: 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
Vytvoří kopii tohoto subrange
objektu , ale s uloženým iterátorem se přesunul zpět za zadanou vzdálenost.
[[nodiscard]] constexpr subrange prev(std::iter_difference_t<I> n = 1 ) const
requires std::bidirectional_iterator<I>;
Parametry
n
Kolik prvků se má iterátor přesunout zpět. Výchozí hodnota je 1. Musí být pozitivní.
Vrácená hodnota
Vrátí kopii objektu subrange
, ale s iterátorem přesunutým zpět n
.
Poznámky
Na rozdíl od advance()
, prev()
nezmění umístění iterátoru uloženého v původním subrange
souboru .
subrange
Vrácená položka obsahuje všechny prvky, které má původní dílčí uspořádání, ale iterátor je jen v jiném umístění. Vrácenou hodnotu si můžete představit takto:
auto tmp = *this;
tmp.advance(-n);
return tmp;
Příklad: 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
Získá počet prvků v souboru subrange
.
constexpr size() const
requires (K == ranges::subrange_kind::sized);
Parametry
Žádná
Vrácená hodnota
Počet prvků v souboru subrange
.
Pokud velikost není uložená, což je případ, kdy subrange
je vytvořen se zadaným K == ranges::subrange_kind::sized
a std::sized_sentinel_for<S, I>
není spokojen, vrátí se velikost jako vzdálenost mezi počátečním a koncovými iterátory.
Změna pozice iterátoru begin
například advance
změní hlášenou velikost.