Compartir a través de


subrange (Clase, Biblioteca estándar de C++)

Proporciona una vista de parte de los elementos de un intervalo tal y como se define en un iterador inicial y un sentinel.

Sintaxis

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

Parámetros de plantilla

I
Tipo de iterador begin. El input_or_output_iterator concepto garantiza que I es un iterador que puede leer todos los elementos.

K
El tipo de subrango: use subrange_kind::sized para especificar un subrango de tamaño. Use sized_sentinel_for<S, I> si el iterador y el centinela se pueden restar para producir el tamaño. El requisito subrange_kind::sized || !sized_sentinel_for<S, I> almacena el tamaño localmente en el objeto de subrango y requiere que construya el subrango mediante el constructor que toma un sized_range (para el que especificaría subrange_kind::sized aquí) o a través del constructor que toma un iterator, sentinely size (por lo que se especificaría sized_sentinel_for<S, I> aquí).

S
Tipo de iterador final. El sized_sentinel_for concepto garantiza que S se puede usar como centinela para I y que es posible calcular la distancia entre el centinela y la posición actual del iterador en I tiempo constante.

Características de la vista

Para obtener una descripción de las siguientes entradas, vea View class characteristics (Ver características de clase).

Característica Descripción
Adaptador de rango views::counted
Intervalo subyacente Cualquier intervalo
Tipo de elemento iter_reference_t<I>
Ver categoría de iterador Igual que Ila categoría
Tamaño Si K es subrange::sized
Es const-iterable Si I es copiable
Rango común Si I y S son del mismo tipo.
Intervalo prestado

Miembros

Funciones miembro Descripción
ConstructoresC++20 Construya un elemento subrange.
operator PairLikeC++20 Convertir un objeto subrange en un tipo similar a un par.
advanceC++20 Mueva el iterador una distancia especificada.
begin Obtenga un iterador al primer elemento.
emptyC++20 Comprueba si el objeto subrange está vacío.
endC++20 Obtenga el centinela al final de .subrange
nextC++20 Crea una copia de esto subrange , pero con el iterador almacenado movido hacia delante la distancia especificada.
prevC++20 Crea una copia de esto subrange , pero con el iterador almacenado movido hacia atrás la distancia especificada.
sizeC++20 Obtiene el número de elementos.
Heredado de view_interface Descripción
backC++20 Obtenga el último elemento.
dataC++20 Obtiene un puntero al primer elemento.
frontC++20 Obtiene el primer elemento.
operator[]C++20 Obtiene el elemento que se encuentra en la posición especificada.
operator boolC++20 Comprueba si el objeto subrange está vacío.

Comentarios

Es subrange útil cuando tiene un iterador inicial y final, pero quiere pasar un solo objeto en su lugar. Por ejemplo, si desea llamar a un adaptador de rango, pero tenía iteradores iniciales y finales, podría usar un subrange para encapsularlos y pasar el subrange al adaptador del rango.

Requisitos

Encabezado: <ranges> (desde C++20)

Espacio de nombres: std::ranges

Opción del compilador: /std:c++20 o posterior es necesaria.

Constructores

Crear un control 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)

Parámetros

begin
Iterador que apunta al primer elemento del subrango.

end
Sentinel que apunta al final del subrango. El elemento al que apunta no se incluye en el subrango.

sizeHint
Tamaño del intervalo en elementos. Esto se usa para optimizar la size función miembro y es necesario si desea realizar un tamaño subrange a partir de un iterador y sentinel cuyos tipos no modelen sized_sentinel_for.

Para obtener información sobre los tipos de parámetros de plantilla, consulte Parámetros de plantilla.

Valor devuelto

Instancia de subrange.

Comentarios

1) El valor predeterminado construye el iterador almacenado y sentinel. La sugerencia de tamaño se establece en 0.
2) Usa std::move() para mover el begin iterador y end sentinel al iterador almacenado y sentinel.
3) Inicializa el iterador almacenado con std::move(begin), el centinela almacenado con std::move(end)y la sugerencia de tamaño almacenada con size, que debe ser igual a la distancia entre los argumentos primero y segundo.
4) Construir un subrange objeto a partir de un intervalo.
5) El comportamiento no se define si szHint != ranges::distance(rg).

El counted adaptador de rango puede crear un subrange. Ese adaptador toma un iterador inicial y un recuento.

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

Convierta un objeto subrange en un tipo que modele pair-like.

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

Parámetros

Ninguno.

Para obtener información sobre los tipos de parámetros de plantilla, consulte Parámetros de plantilla.

Valor devuelto

Valor PairLike que se inicializa directamente con el iterador almacenado y sentinel. El último valor del par será el centinela.

Recuerde que el sentinel está más allá del último elemento del subrango, como se muestra en el ejemplo siguiente.

Comentarios

Esta conversión es útil con código anterior Boost::Ranges que acepta pares (primero, último) para indicar un intervalo.
Esta conversión es útil para convertir un subrango en u pair tuple otro tipo que modele pair_like. Algunos ejemplos de pair_like tipos son:

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

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

Ajuste el iterador para esto subrange por n elementos.

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

Parámetros

n
Cuántos elementos se van a ajustar el iterador. n puede ser positivo (avanzar) o, si I es bidireccional, negativo (retroceder).

Comentarios

Esta función modifica el estado actual del iterador en .subrange

Si avanza más allá del final de subrange, el iterador se establece en el centinela al final de subrange.
Si avanza más allá del principio de subrange (con un valor negativo n), obtendrá una excepción de parámetro no válida si el intervalo desde el que realizó subrange no tiene ningún elemento en el lugar.

Por ejemplo, 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

Obtenga un iterador al primer elemento de .subrange

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

Parámetros

Ninguno.

Valor devuelto

Iterador que apunta al primer elemento de subrange. Si el iterador no se puede copiar, se devuelve con std::move(). Si se mueve el iterador, el estado del iterador almacenado depende de la implementación del constructor de movimiento para I.

Imagen de un vector con los elementos 10, 20 y 30. El primer elemento contiene 10 y se etiqueta begin(). El último elemento contiene 30 y se etiqueta como

empty

Comprueba si el objeto subrange está vacío.

constexpr bool empty() const;

Parámetros

Ninguno.

Valor devuelto

Devuelve true si no subrange tiene elementos. De lo contrario, devuelve false.

end

Obtención del centinela al final del subrange

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

Parámetros

Ninguno.

Valor devuelto

Sentinel que sigue al último elemento de subrange:

Imagen de un vector con los elementos 10, 20 y 30. El primer elemento contiene 10 y se etiqueta begin(). El último elemento contiene 30 y se etiqueta como

El sentinel se copia a partir del centinela almacenado.

next

Crea una copia de esto subrange , pero con el iterador almacenado movido hacia delante la distancia especificada.

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

Parámetros

n
Cuántos elementos se van a mover al iterador hacia delante. De manera predeterminada, su valor es 1. Debe ser positivo.

Valor devuelto

Devuelve una copia del subrange elemento que comienza en el elemento *n*th.

Comentarios

A diferencia advance()de , next() no cambia la ubicación del iterador almacenado en el original subrange. El devuelto subrange tiene todos los elementos que tiene el subrango original, pero el iterador está en una ubicación diferente.

1) El valor devuelto es el mismo que:

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

2) El valor devuelto es el mismo que:

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

Ejemplo: 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 de este subrange, pero con el iterador almacenado movido hacia atrás la distancia especificada.

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

Parámetros

n
Cuántos elementos se van a devolver al iterador. De manera predeterminada, su valor es 1. Debe ser positivo.

Valor devuelto

Devuelve una copia de pero subrange con el iterador movidos hacia atrás n .

Comentarios

A diferencia advance()de , prev() no cambia la ubicación del iterador almacenado en el original subrange.
El devuelto subrange tiene todos los elementos que tiene el subrango original, pero el iterador se encuentra en una ubicación diferente. Puede considerar el valor devuelto como:

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

Por ejemplo, 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

Obtiene el número de elementos de subrange.

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

Parámetros

Ninguno.

Valor devuelto

Número de elementos incluidos en subrange.

Si el tamaño no se almacena, que es el caso cuando subrange se crea con K == ranges::subrange_kind::sized especificado y std::sized_sentinel_for<S, I> no se cumple, el tamaño se devuelve como la distancia entre los iteradores inicial y final.

Cambiar la posición del begin iterador, con advance, por ejemplo, cambia el tamaño notificado.

Consulte también

<ranges>
counted
Ver clases