Sdílet prostřednictvím


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 , sentinela 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 Ikategorie 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 PairLikeC++20 subrange Převeďte typ podobný páru.
advanceC++20 Přesuňte iterátor o zadanou vzdálenost.
begin Získejte iterátor k prvnímu prvku.
emptyC++20 Otestujte, jestli subrange je prázdný.
endC++20 Získejte sentinel na konci subrange.
nextC++20 Vytvoří kopii tohoto subrange objektu, ale s uloženým iterátorem se posune o zadanou vzdálenost.
prevC++20 Vytvoří kopii tohoto subrange objektu, ale s uloženým iterátorem se přesune zpět za zadanou vzdálenost.
sizeC++20 Získá počet prvků.
Zděděno z view_interface Popis
backC++20 Získejte poslední prvek.
dataC++20 Získejte ukazatel na první prvek.
frontC++20 Získejte první prvek.
operator[]C++20 Získejte prvek na zadané pozici.
operator boolC++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 subrangemůž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é nhodnoty 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.

Obrázek vektoru s prvky 10, 20 a 30 První prvek obsahuje hodnotu 10 a je označen jako begin(). Poslední prvek obsahuje hodnotu 30 a je označený jako

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

Obrázek vektoru s prvky 10, 20 a 30 První prvek obsahuje hodnotu 10 a je označen jako begin(). Poslední prvek obsahuje hodnotu 30 a je označený jako

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 subrangesouboru . 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 subrangeobjektu , 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 subrangesouboru .
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 advancezmění hlášenou velikost.

Viz také

<ranges>
counted
Zobrazit třídy