Partager via


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, sentinelet 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 à Ila 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 PairLikeC++20 Convertissez un subrange type semblable à une paire.
advanceC++20 Déplacez l’itérateur à une distance spécifiée.
begin Obtenez un itérateur au premier élément.
emptyC++20 Testez si la valeur subrange est vide.
endC++20 Obtenez la sentinelle à la fin du subrange.
nextC++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.
prevC++20 Crée une copie de cette subrange opération, mais avec l’itérateur stocké déplacé la distance spécifiée.
sizeC++20 Obtenez le nombre d’éléments.
Hérité de view_interface Description
backC++20 Obtenez le dernier élément.
dataC++20 Obtenez un pointeur vers le premier élément.
frontC++20 Obtenez le premier élément.
operator[]C++20 Obtenez l’élément à la position spécifiée.
operator boolC++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_forpas .

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.

Image d’un vecteur avec les éléments 10, 20 et 30. Le premier élément contient 10 et est étiqueté begin(). Le dernier élément contient 30 et est intitulé « dernier élément ». Une zone imaginaire après le dernier élément indique la sentinelle et est étiquetée end().

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:

Image d’un vecteur avec les éléments 10, 20 et 30. Le premier élément contient 10 et est étiqueté begin(). Le dernier élément contient 30 et est intitulé « dernier élément ». Une zone imaginaire après le dernier élément indique la sentinelle et est étiquetée end().

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 subrangemessage, 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 advanceexemple, modifie la taille signalée.

Voir aussi

<ranges>
counted
Afficher les classes