Condividi tramite


subrange classe (libreria standard C++)

Fornisce una visualizzazione di parte degli elementi di un intervallo come definito da un iteratore iniziale e sentinella.

Sintassi

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>>

Parametri del modello

I
Tipo di iteratore di inizio. Il input_or_output_iterator concetto garantisce che I sia un iteratore in grado di leggere tutti gli elementi.

K
Tipo di intervallo secondario: usare subrange_kind::sized per specificare un intervallo secondario di dimensioni. Usare sized_sentinel_for<S, I> se l'iteratore e sentinel possono essere sottratti per produrre le dimensioni. Il requisito subrange_kind::sized || !sized_sentinel_for<S, I> archivia le dimensioni in locale nell'oggetto del sottorange e richiede di costruire il sottoinsieme usando il costruttore che accetta ( sized_range per il quale si specifica subrange_kind::sized qui) o tramite il costruttore che accetta un iteratoroggetto , sentinele size (in modo da specificare sized_sentinel_for<S, I> qui).

S
Tipo di iteratore finale. Il sized_sentinel_for concetto garantisce che S possa essere usato come sentinel per I e che sia possibile calcolare la distanza tra sentinel e la posizione iteratore corrente in I tempo costante.

Visualizzare le caratteristiche

Per una descrizione delle voci seguenti, vedere Visualizzare le caratteristiche della classe

Caratteristica Descrizione
Adattatore di intervallo views::counted
Intervallo sottostante Qualsiasi intervallo
Tipo di elemento iter_reference_t<I>
Visualizzare la categoria iteratore Uguale alla Icategoria s
Dimensioni Se K è subrange::sized
Iterabile const Se I è copiabile
Intervallo comune Se I e S sono dello stesso tipo.
Intervallo preso in prestito

Membri

Funzioni membro Descrizione
Costruttori C++20 Creare un oggetto subrange.
operator PairLikeC++20 Convertire un oggetto subrange in un tipo simile a una coppia.
advanceC++20 Spostare l'iteratore a una distanza specificata.
begin Ottenere un iteratore al primo elemento.
emptyC++20 Verificare se l'oggetto subrange è vuoto.
endC++20 Ottenere il sentinel alla fine dell'oggetto subrange.
nextC++20 Crea una copia di questo subrange oggetto, ma con l'iteratore archiviato spostato in avanti la distanza specificata.
prevC++20 Crea una copia di questo subrange oggetto, ma con l'iteratore archiviato spostato indietro la distanza specificata.
sizeC++20 Ottiene il numero di elementi.
Ereditato da view_interface Descrizione
backC++20 Ottiene l'ultimo elemento.
dataC++20 Ottenere un puntatore al primo elemento.
frontC++20 Ottenere il primo elemento.
operator[]C++20 Ottiene l'elemento nella posizione specificata.
operator boolC++20 Verificare se l'oggetto subrange è vuoto.

Osservazioni:

Un subrange oggetto è utile quando si dispone di un iteratore iniziale e finale, ma si vuole passare un singolo oggetto. Ad esempio, se si desidera chiamare un adattatore di intervallo ma aveva iteratori di inizio e fine, è possibile usare un subrange oggetto per eseguirne il wrapping e passare l'oggetto subrange all'adattatore di intervallo.

Requisiti

Intestazione: <ranges> (da C++20)

Spazio dei nomi: std::ranges

Opzione del compilatore: /std:c++20 o versione successiva è obbligatoria.

Costruttori

Creare un oggetto 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)

Parametri

begin
Iteratore che punta al primo elemento nell'intervallo secondario.

end
Sentinel che punta alla fine del sottoinsieme. L'elemento a cui punta non è incluso nell'intervallo secondario.

sizeHint
Dimensione dell'intervallo negli elementi. Viene usato per ottimizzare la size funzione membro ed è necessario se si desidera creare una dimensione subrange da un iteratore e sentinel i cui tipi non modellano sized_sentinel_for.

Per informazioni sui tipi di parametri del modello, vedere Parametri del modello.

Valore restituito

Istanza di subrange.

Osservazioni:

1) Il valore predefinito costruisce l'iteratore archiviato e sentinel. L'hint per le dimensioni è impostato su 0.
2) Usa std::move() per spostare l'iteratore begin e end sentinel nell'iteratore archiviato e sentinel.
3) Inizializza l'iteratore archiviato con std::move(begin), l'oggetto sentinel archiviato con std::move(end)e l'hint per le dimensioni archiviate con size, che deve essere uguale alla distanza tra il primo e il secondo argomento.
4) Costruire un oggetto subrange da un intervallo.
5) Il comportamento non è definito se szHint != ranges::distance(rg).

L'adattatore counted di intervallo può creare un oggetto subrange. Tale adattatore accetta un iteratore di inizio e un conteggio.

Esempio: 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

Convertire un oggetto subrange in un tipo che modella pair-like.

template<not-same-as<subrange> PairLike>
requires pair-like-convertible-from<PairLike, const I&, const S&>
constexpr operator PairLike() const;

Parametri

Nessuna.

Per informazioni sui tipi di parametri del modello, vedere Parametri del modello.

Valore restituito

Valore PairLike inizializzato direttamente con l'iteratore archiviato e sentinel. L'ultimo valore nella coppia sarà sentinel.

Tenere presente che sentinel è passato l'ultimo elemento nell'intervallo secondario, come illustrato nell'esempio seguente.

Osservazioni:

Questa conversione è utile con il codice precedente Boost::Ranges che accetta coppie (prima, ultima) per indicare un intervallo.
Questa conversione è utile per convertire un intervallo secondario in un pair tipo o tuple in un altro tipo che modella pair_like. Ecco alcuni esempi di pair_like tipi:

std::array<T, 2>
std::pair<T, U>
std::ranges::subrange<I, S, K>
std::tuple<T, U>

Esempio: 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

Regolare l'iteratore per questo subrange oggetto in base agli n elementi.

constexpr subrange& advance(const iter_difference_t<I> n);

Parametri

n
Numero di elementi per regolare l'iteratore. n può essere positivo (spostarsi in avanti) o, se I è bidirezionale, negativo (spostarsi all'indietro).

Osservazioni:

Questa funzione modifica lo stato corrente dell'iteratore nell'oggetto subrange.

Se si passa oltre la fine di subrange, l'iteratore viene impostato su sentinel alla fine di subrange.
Se si avanza oltre l'inizio di subrange (usando un valore negativo n), si otterrà un'eccezione di parametro non valida se l'intervallo da creato subrange non ha un elemento sul posto.

Esempioadvance

// 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

Ottenere un iteratore al primo elemento dell'oggetto subrange.

1) constexpr I begin() const requires copyable<I>;
2) [[nodiscard]] constexpr I begin() requires (!std::copyable<I>);

Parametri

Nessuna.

Valore restituito

Iteratore che punta al primo elemento dell'oggetto subrange. Se l'iteratore non è copiabile, viene restituito con std::move(). Se l'iteratore viene spostato, lo stato dell'iteratore archiviato dipende dall'implementazione del costruttore di spostamento per I.

Immagine di un vettore con gli elementi 10, 20 e 30. Il primo elemento contiene 10 ed è etichettato begin(). L'ultimo elemento contiene 30 e viene etichettato come 'ultimo elemento'. Una casella immaginaria dopo l'ultimo elemento indica la sentinella ed è etichettata end().

empty

Verificare se l'oggetto subrange è vuoto.

constexpr bool empty() const;

Parametri

Nessuna.

Valore restituito

Restituisce true se l'oggetto subrange non dispone di elementi. In caso contrario, restituisce false.

end

Ottenere la sentinella alla fine del subrange

[[nodiscard]] constexpr S end() const;

Parametri

Nessuna.

Valore restituito

Sentinel che segue l'ultimo elemento in subrange:

Immagine di un vettore con gli elementi 10, 20 e 30. Il primo elemento contiene 10 ed è etichettato begin(). L'ultimo elemento contiene 30 e viene etichettato come 'ultimo elemento'. Una casella immaginaria dopo l'ultimo elemento indica la sentinella ed è etichettata end().

Sentinel viene creato in copia dalla sentinel archiviata.

next

Crea una copia di questo subrange oggetto, ma con l'iteratore archiviato spostato in avanti la distanza specificata.

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) &&;

Parametri

n
Numero di elementi per spostare l'iteratore in avanti. Assume il valore predefinito 1. Deve essere positivo.

Valore restituito

Restituisce una copia dell'oggetto subrange a partire dall'elemento *n*th.

Osservazioni:

A differenza di advance(), next() non modifica la posizione dell'iteratore archiviato nell'oggetto originale subrange. L'oggetto restituito subrange contiene tutti gli elementi del sottorange originale, ma l'iteratore si trova in una posizione diversa.

1) Il valore restituito è uguale a:

auto tmp = *this;
tmp.advance(n);
return tmp;

2) Il valore restituito è uguale a:

advance(n);
return std::move(*this);

Esempio: 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

Crea una copia di questo subrangeoggetto , ma con l'iteratore archiviato spostato indietro la distanza specificata.

[[nodiscard]] constexpr subrange prev(std::iter_difference_t<I> n = 1 ) const
    requires std::bidirectional_iterator<I>;

Parametri

n
Numero di elementi per spostare nuovamente l'iteratore. Assume il valore predefinito 1. Deve essere positivo.

Valore restituito

Restituisce una copia dell'oggetto subrange ma con gli elementi iteratori spostati indietro n .

Osservazioni:

A differenza di advance(), prev() non modifica la posizione dell'iteratore archiviato nell'oggetto originale subrange.
L'oggetto restituito subrange contiene tutti gli elementi del sottorange originale, ma l'iteratore si trova solo in una posizione diversa. È possibile considerare il valore restituito come:

auto tmp = *this;
tmp.advance(-n);
return tmp;

Esempioprev

// 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

Ottiene il numero di elementi nell'oggetto subrange.

constexpr size() const
    requires (K == ranges::subrange_kind::sized);

Parametri

Nessuna.

Valore restituito

Numero di elementi in subrange.

Se le dimensioni non vengono archiviate, ovvero quando l'oggetto subrange viene creato con K == ranges::subrange_kind::sized specificato e std::sized_sentinel_for<S, I> non è soddisfatto, le dimensioni vengono restituite come distanza tra gli iteratori iniziale e finale.

La modifica della posizione dell'iteratore begin , con advance, ad esempio, modifica le dimensioni segnalate.

Vedi anche

<ranges>
counted
Visualizzare le classi