Freigeben über


subrange Klasse (C++-Standardbibliothek)

Stellt eine Ansicht eines Teils der Elemente eines Bereichs bereit, wie durch einen Begin Iterator und Sentinel definiert.

Syntax

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

Vorlagenparameter

I
Der Anfangs iteratortyp. Das input_or_output_iterator Konzept stellt sicher, dass es I sich um einen Iterator handelt, der alle Elemente lesen kann.

K
Die Art des Unterbereichs: Wird subrange_kind::sized verwendet, um einen Unterbereich der Größe anzugeben. Wird sized_sentinel_for<S, I> verwendet, wenn der Iterator und sentinel subtrahiert werden können, um die Größe zu erzielen. Die Anforderung subrange_kind::sized || !sized_sentinel_for<S, I> speichert die Größe lokal im Unterbereichsobjekt und erfordert, dass Sie die Unterrange entweder mithilfe des Konstruktors erstellen, der einen sized_range (für den Sie hier angeben subrange_kind::sized würden) oder über den Konstruktor, der ein iterator, sentinel, und size (so würden Sie hier angeben sized_sentinel_for<S, I> ).

S
Der End iteratortyp. Das sized_sentinel_for Konzept stellt sicher, dass es S als Sentinel I verwendet werden kann und dass es möglich ist, den Abstand zwischen dem Sentinel und der aktuellen Iteratorposition in I konstanter Zeit zu berechnen.

Eigenschaften der Ansicht

Eine Beschreibung der folgenden Einträge finden Sie unter Anzeigen von Klassenmerkmalen

Merkmal Beschreibung
Range Adaptor views::counted
Zugrunde liegender Bereich Beliebiger Bereich
Elementtyp iter_reference_t<I>
Iteratorkategorie anzeigen Identisch mit Ider Kategorie
Größer eingestellt Wenn K gleich subrange::sized
Ist const-iterierbar Wenn I kopierbar
Allgemeiner Bereich Wenn I und S sind derselbe Typ.
Geliehener Bereich Ja

Member

Memberfunktionen Beschreibung
Konstruktoren C++20 Erstellen Sie ein subrange.
operator PairLikeC++20 Konvertieren sie einen subrange in einen typähnlichen Typ.
advanceC++20 Verschieben sie den Iterator um einen angegebenen Abstand.
begin Rufen Sie einen Iterator zum ersten Element ab.
emptyC++20 Testen Sie, ob die Datei subrange leer ist.
endC++20 Rufen Sie den Sentinel am Ende der .subrange
nextC++20 Erstellt eine Kopie davon subrange , wobei der gespeicherte Iterator jedoch den angegebenen Abstand vorwärts verschoben hat.
prevC++20 Erstellt eine Kopie davon subrange , aber mit dem gespeicherten Iterator wurde der angegebene Abstand zurück verschoben.
sizeC++20 Ruft die Anzahl der Elemente ab.
Geerbt von view_interface Beschreibung
backC++20 Rufen Sie das letzte Element ab.
dataC++20 Rufen Sie einen Zeiger auf das erste Element ab.
frontC++20 Rufen Sie das erste Element ab.
operator[]C++20 Rufen Sie das Element an der angegebenen Position ab.
operator boolC++20 Testen Sie, ob die Datei subrange leer ist.

Hinweise

Eine subrange ist nützlich, wenn Sie einen Anfangs- und End iterator haben, aber stattdessen ein einzelnes Objekt übergeben möchten. Wenn Sie z. B. einen Bereichsadapter aufrufen möchten, aber die Iteratoren beginnen und beenden wollten, können Sie sie mit einem subrange Umbruch versehen und den subrange Bereichsadapter übergeben.

Anforderungen

Header: <ranges> (seit C++20)

Namespace:std::ranges

Compileroption: /std:c++20 oder höher ist erforderlich.

Konstruktoren

Erstellen Sie eine 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)

Parameter

begin
Iterator, der auf das erste Element im Unterbereich verweist.

end
Sentinel, das auf das Ende des Unterbereichs zeigt. Das Element, auf das es verweist, ist nicht in der Unterrange enthalten.

sizeHint
Die Größe des Bereichs in Elementen. Dies wird verwendet, um die size Memberfunktion zu optimieren und ist erforderlich, wenn Sie eine Größe subrange von einem Iterator und Sentinel erstellen möchten, dessen Typen nicht modellieren sized_sentinel_for.

Informationen zu Vorlagenparametertypen finden Sie unter Vorlagenparameter.

Rückgabewert

Eine subrange-Instanz.

Hinweise

1) Standardkonstrukte für den gespeicherten Iterator und Sentinel. Der Größenhinweis ist auf 0 festgelegt.
2) Verwendet std::move() , um den begin Iterator und end Sentinel in den gespeicherten Iterator und Sentinel zu verschieben.
3) Initialisiert den gespeicherten Iterator mit std::move(begin), dem gespeicherten Sentinel mit std::move(end), und den gespeicherten Größenhinweis mit size, der dem Abstand zwischen den ersten und zweiten Argumenten entspricht.
4) Erstellen sie aus subrange einem Bereich.
5) Das Verhalten wird nicht definiert, wenn szHint != ranges::distance(rg).

Der counted Bereichsadapter kann eine subrange. Dieser Adaptor nimmt einen Anfangs-Iterator und eine Anzahl an.

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

Konvertieren sie einen subrange in einen Typ, der modelliert pair-like.

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

Parameter

Keine.

Informationen zu Vorlagenparametertypen finden Sie unter Vorlagenparameter.

Rückgabewert

Ein PairLike Wert, der mit dem gespeicherten Iterator und Sentinel direkt initialisiert wird. Der letzte Wert im Paar ist der Sentinel.

Denken Sie daran, dass der Sentinel über das letzte Element im Unterbereich liegt , wie im folgenden Beispiel gezeigt.

Hinweise

Diese Konvertierung ist bei älteren Boost::Ranges Code hilfreich, der (erste, letzte) Paare akzeptiert, um einen Bereich zu kennzeichnen.
Diese Konvertierung ist nützlich, um einen Unterbereich in einen pair oder tuple einen anderen Typ zu konvertieren, der modelliert pair_like. Einige Beispiele für pair_like Typen sind:

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

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

Passen Sie den Iterator dafür subrange nach n Elementen an.

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

Parameter

n
Anzahl der Elemente zum Anpassen des Iterators. n kann positiv (vorwärts) oder, wenn I es sich um bidirektionale, negative (Rückwärtsbewegung) handelt.

Hinweise

Diese Funktion ändert den aktuellen Zustand des Iterators in der subrange.

Wenn Sie über das Ende des Bereichs subrangehinaus gehen, wird der Iterator am Ende des subrangeWächters auf den Sentinel festgelegt.
Wenn Sie den Anfang des subrange (unter Verwendung eines negativen n) voranschreiten, erhalten Sie eine ungültige Parameter-Ausnahme, wenn der Bereich, aus dem Sie den subrange Bereich erstellt haben, kein Element an der Stelle hat.

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

Rufen Sie einen Iterator zum ersten Element in der subrange.

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

Parameter

Keine

Rückgabewert

Ein Iterator, der auf das erste Element in der subrange. Wenn der Iterator nicht kopierbar ist, wird er mit std::move(). Wenn der Iterator verschoben wird, hängt der Zustand des gespeicherten Iterators von der Implementierung des Verschiebungskonstruktors ab.I

Abbildung eines Vektors mit den Elementen 10, 20 und 30. Das erste Element enthält 10 und ist mit

empty

Testen Sie, ob die Datei subrange leer ist.

constexpr bool empty() const;

Parameter

Keine

Rückgabewert

Gibt zurück true , wenn keine subrange Elemente vorhanden sind. Andernfalls wird falsezurückgegeben.

end

Abrufen des Sentinels am Ende des subrange

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

Parameter

Keine

Rückgabewert

Der Sentinel, der auf das letzte Element in der subrange:

Abbildung eines Vektors mit den Elementen 10, 20 und 30. Das erste Element enthält 10 und ist mit

Der Sentinel wird aus dem gespeicherten Sentinel kopiert.

next

Erstellt eine Kopie davon subrange , wobei der gespeicherte Iterator jedoch den angegebenen Abstand vorwärts verschoben hat.

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

Parameter

n
Anzahl der Elemente, die der Iterator vorwärts verschieben soll. Der Standardwert lautet 1. Muss positiv sein.

Rückgabewert

Gibt eine Kopie des subrange Anfangs am *n*-th-Element zurück.

Hinweise

Im Gegensatz dazu advance()next() ändert sich nicht die Position des Iterators, der im Original subrangegespeichert ist. Der Zurückgegebene subrange verfügt über alle Elemente, die der ursprüngliche Unterbereich aufweist, der Iterator befindet sich jedoch an einer anderen Position.

1) Der Rückgabewert ist identisch mit:

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

2) Der Rückgabewert ist identisch mit:

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

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

Erstellt eine Kopie dieses subrangeWerts, aber mit dem gespeicherten Iterator wurde der angegebene Abstand zurück verschoben.

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

Parameter

n
Wie viele Elemente der Iterator zurück verschoben werden sollen. Der Standardwert lautet 1. Muss positiv sein.

Rückgabewert

Gibt eine Kopie der subrange Aber mit dem Iterator zurück verschobene n Elemente zurück.

Hinweise

Im Gegensatz dazu advance()prev() ändert sich nicht die Position des Iterators, der im Original subrangegespeichert ist.
Das zurückgegebene Element subrange weist alle Elemente auf, die der ursprüngliche Unterbereich aufweist, der Iterator befindet sich jedoch nur an einer anderen Position. Sie können sich den Rückgabewert wie:

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

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

Ruft die Anzahl der Elemente in der subrange.

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

Parameter

Keine

Rückgabewert

Die Anzahl der Elemente im subrange.

Wenn die Größe nicht gespeichert ist. Dies ist der Fall, wenn die subrange Größe mit K == ranges::subrange_kind::sized dem angegebenen Wert erstellt und std::sized_sentinel_for<S, I> nicht erfüllt ist, wird die Größe als Abstand zwischen dem Anfangs- und End iterator zurückgegeben.

Wenn Sie die Position des begin Iterators ändern, advancez. B. wird die gemeldete Größe geändert.

Siehe auch

<ranges>
counted
Anzeigen von Klassen