subrange
classe (bibliothèque standard C++)
Fournit une vue d’une partie des éléments d’une plage tel que défini par un itérateur de début et une sentinelle.
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>>
Paramètres de modèle
I
Type d’itérateur de début. Le input_or_output_iterator
concept garantit qu’il I
s’agit d’un itérateur capable de lire tous les éléments.
K
Type de sous-plage : permet subrange_kind::sized
de spécifier une sous-plage de taille. Utilisez sized_sentinel_for<S, I>
si l’itérateur et la sentinelle peuvent être soustraits pour produire la taille. La condition requise subrange_kind::sized || !sized_sentinel_for<S, I>
stocke la taille localement dans l’objet de sous-plage et exige que vous construisiez la sous-plage à l’aide du constructeur qui accepte un sized_range
(pour lequel vous spécifiez subrange_kind::sized
ici) ou via le constructeur qui prend un iterator
, sentinel
et size
(vous devez donc spécifier sized_sentinel_for<S, I>
ici).
S
Type d’itérateur de fin. Le sized_sentinel_for
concept garantit qu’il S
peut être utilisé comme sentinelle et I
qu’il est possible de calculer la distance entre la sentinelle et la position d’itérateur actuelle en I
temps constant.
Afficher les caractéristiques
Pour obtenir une description des entrées suivantes, consultez les caractéristiques de classe View
Caractéristique | Description |
---|---|
Adaptateur de plage | views::counted |
Plage sous-jacente | Toute plage |
Type d’élément | iter_reference_t<I> |
Afficher la catégorie d’itérateur | Identique à I la catégorie |
Taille | Si K est subrange::sized |
Est const -itérable |
S’il I est copieux |
Plage commune | Si I et S sont du même type. |
Plage empruntée | Oui |
Membres
Fonctions membres | Description |
---|---|
Constructeurs C++20 | Construisez un subrange . |
operator PairLike C++20 |
Convertissez un subrange type semblable à une paire. |
advance C++20 |
Déplacez l’itérateur à une distance spécifiée. |
begin |
Obtenez un itérateur au premier élément. |
empty C++20 |
Testez si la valeur subrange est vide. |
end C++20 |
Obtenez la sentinelle à la fin du subrange . |
next C++20 |
Crée une copie de cette subrange opération, mais avec l’itérateur stocké déplacé vers l’avant la distance spécifiée. |
prev C++20 |
Crée une copie de cette subrange opération, mais avec l’itérateur stocké déplacé la distance spécifiée. |
size C++20 |
Obtenez le nombre d’éléments. |
Hérité de view_interface |
Description |
back C++20 |
Obtenez le dernier élément. |
data C++20 |
Obtenez un pointeur vers le premier élément. |
front C++20 |
Obtenez le premier élément. |
operator[] C++20 |
Obtenez l’élément à la position spécifiée. |
operator bool C++20 |
Testez si la valeur subrange est vide. |
Notes
Il subrange
est utile lorsque vous avez un itérateur de début et de fin, mais que vous souhaitez passer un seul objet à la place. Par exemple, si vous vouliez appeler un adaptateur de plage mais qu’il avait des itérateurs de début et de fin, vous pouvez utiliser un subrange
wrapper pour les encapsuler et passer l’adaptateur subrange
de plage.
Spécifications
En-tête : <ranges>
(depuis C++20)
Espace de noms : std::ranges
Option du compilateur : /std:c++20
ou version ultérieure est requise.
Constructeurs
Créer un 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)
Paramètres
begin
Itérateur qui pointe vers le premier élément de la sous-plage.
end
Sentinel qui pointe vers la fin de la sous-plage. L’élément auquel il pointe n’est pas inclus dans la sous-plage.
sizeHint
Taille de la plage dans les éléments. Cela permet d’optimiser la fonction membre et est nécessaire si vous souhaitez effectuer une taille subrange
à partir d’un itérateur et d’une sentinelle dont les size
types ne modélisent sized_sentinel_for
pas .
Pour plus d’informations sur les types de paramètres de modèle, consultez Paramètres de modèle.
Valeur retournée
Instance de subrange
.
Notes
1) Construit par défaut l’itérateur stocké et la sentinelle. L’indicateur de taille est défini sur 0.
2) Utilise std::move()
pour déplacer l’itérateur et end
la begin
sentinelle vers l’itérateur stocké et sentinelle.
3) Initialise l’itérateur stocké avec std::move(begin)
, la sentinelle stockée avec std::move(end)
, et l’indicateur de taille stockée avec size
, qui doit correspondre à la distance entre les premiers et deuxième arguments.
4) Construire une subrange
plage à partir d’une plage.
5) Le comportement n’est pas défini si szHint != ranges::distance(rg)
.
L’adaptateur counted
de plage peut créer un subrange
. Cet adaptateur prend un itérateur de début et un nombre.
Exemple : 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
Convertissez un subrange
type qui modélise pair-like
.
template<not-same-as<subrange> PairLike>
requires pair-like-convertible-from<PairLike, const I&, const S&>
constexpr operator PairLike() const;
Paramètres
Aucune.
Pour plus d’informations sur les types de paramètres de modèle, consultez Paramètres de modèle.
Valeur retournée
Valeur PairLike
qui est initialisée directement avec l’itérateur stocké et sentinelle.
La dernière valeur de la paire sera la sentinelle.
N’oubliez pas que la sentinelle est passée au-delà du dernier élément de la sous-plage, comme illustré dans l’exemple ci-dessous.
Notes
Cette conversion est utile avec un code plus ancien Boost::Ranges
qui accepte (d’abord, dernière) paires pour désigner une plage.
Cette conversion est utile pour convertir une sous-plage en un pair
ou tuple
un autre type qui modélise pair_like
. Voici quelques exemples de pair_like
types :
std::array<T, 2>
std::pair<T, U>
std::ranges::subrange<I, S, K>
std::tuple<T, U>
Exemple : 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
Ajustez l’itérateur pour cela subrange
par n
les éléments.
constexpr subrange& advance(const iter_difference_t<I> n);
Paramètres
n
Nombre d’éléments à ajuster à l’itérateur. n
peut être positif (avancer) ou, s’il I
est bidirectionnel, négatif (reculer).
Notes
Cette fonction modifie l’état actuel de l’itérateur dans le subrange
.
Si vous avancez au-delà de la fin du subrange
, l’itérateur est défini sur la sentinelle à la fin du subrange
.
Si vous avancez au-delà du début du (à l’aide subrange
d’un négatif n
), vous obtiendrez une exception de paramètre non valide si la plage à partir de laquelle vous avez effectué l’élément subrange
n’a pas d’élément à la place.
Exemple 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
Obtenez un itérateur au premier élément du subrange
.
1) constexpr I begin() const requires copyable<I>;
2) [[nodiscard]] constexpr I begin() requires (!std::copyable<I>);
Paramètres
Aucune.
Valeur retournée
Itérateur pointant vers le premier élément du subrange
.
Si l’itérateur n’est pas copieur, il est retourné avec std::move()
. Si l’itérateur est déplacé, l’état de l’itérateur stocké dépend de l’implémentation du constructeur de déplacement pour I
.
empty
Testez si la valeur subrange
est vide.
constexpr bool empty() const;
Paramètres
Aucune.
Valeur retournée
Retourne true
si l’élément n’a subrange
aucun élément. Sinon, retourne false
.
end
Obtenir la sentinelle à la fin de la subrange
[[nodiscard]] constexpr S end() const;
Paramètres
Aucune.
Valeur retournée
Sentinel qui suit le dernier élément dans le subrange
:
La sentinelle est construite à partir de la sentinelle stockée.
next
Crée une copie de cette subrange
opération, mais avec l’itérateur stocké déplacé vers l’avant la distance spécifiée.
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) &&;
Paramètres
n
Nombre d’éléments à déplacer vers l’avant. La valeur par défaut est de 1. Doit être positif.
Valeur retournée
Retourne une copie du subrange
début à l’élément *n
*th.
Notes
Contrairement advance()
à , next()
ne modifie pas l’emplacement de l’itérateur stocké dans l’original subrange
.
Le retour subrange
contient tous les éléments dont la sous-plage d’origine a, mais l’itérateur se trouve dans un autre emplacement.
1) La valeur de retour est la même que :
auto tmp = *this;
tmp.advance(n);
return tmp;
2) La valeur de retour est la même que :
advance(n);
return std::move(*this);
Exemple : 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
Crée une copie de ce subrange
message, mais avec l’itérateur stocké déplacé la distance spécifiée.
[[nodiscard]] constexpr subrange prev(std::iter_difference_t<I> n = 1 ) const
requires std::bidirectional_iterator<I>;
Paramètres
n
Nombre d’éléments à déplacer vers le retour de l’itérateur. La valeur par défaut est de 1. Doit être positif.
Valeur retournée
Retourne une copie de l’itérateursubrange
, mais avec l’itérateur déplacé les éléments.n
Notes
Contrairement advance()
à , prev()
ne modifie pas l’emplacement de l’itérateur stocké dans l’original subrange
.
Le retour subrange
contient tous les éléments dont la sous-plage d’origine a, mais l’itérateur se trouve juste à un autre emplacement. Vous pouvez considérer la valeur de retour comme suit :
auto tmp = *this;
tmp.advance(-n);
return tmp;
Exemple 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
Obtenir le nombre d’éléments dans le subrange
.
constexpr size() const
requires (K == ranges::subrange_kind::sized);
Paramètres
Aucune.
Valeur retournée
Nombre d'éléments dans subrange
.
Si la taille n’est pas stockée, c’est-à-dire lorsque la subrange
taille est créée avec K == ranges::subrange_kind::sized
spécifiée et std::sized_sentinel_for<S, I>
n’est pas satisfaite, la taille est retournée comme distance entre les itérateurs de début et de fin.
La modification de la position de l’itérateur begin
, par advance
exemple, modifie la taille signalée.