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
, sentinel
y 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 I la 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 | Sí |
Miembros
Funciones miembro | Descripción |
---|---|
ConstructoresC++20 | Construya un elemento subrange . |
operator PairLike C++20 |
Convertir un objeto subrange en un tipo similar a un par. |
advance C++20 |
Mueva el iterador una distancia especificada. |
begin |
Obtenga un iterador al primer elemento. |
empty C++20 |
Comprueba si el objeto subrange está vacío. |
end C++20 |
Obtenga el centinela al final de .subrange |
next C++20 |
Crea una copia de esto subrange , pero con el iterador almacenado movido hacia delante la distancia especificada. |
prev C++20 |
Crea una copia de esto subrange , pero con el iterador almacenado movido hacia atrás la distancia especificada. |
size C++20 |
Obtiene el número de elementos. |
Heredado de view_interface |
Descripción |
back C++20 |
Obtenga el último elemento. |
data C++20 |
Obtiene un puntero al primer elemento. |
front C++20 |
Obtiene el primer elemento. |
operator[] C++20 |
Obtiene el elemento que se encuentra en la posición especificada. |
operator bool C++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
.
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
:
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.