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 I der 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 PairLike C++20 |
Konvertieren sie einen subrange in einen typähnlichen Typ. |
advance C++20 |
Verschieben sie den Iterator um einen angegebenen Abstand. |
begin |
Rufen Sie einen Iterator zum ersten Element ab. |
empty C++20 |
Testen Sie, ob die Datei subrange leer ist. |
end C++20 |
Rufen Sie den Sentinel am Ende der .subrange |
next C++20 |
Erstellt eine Kopie davon subrange , wobei der gespeicherte Iterator jedoch den angegebenen Abstand vorwärts verschoben hat. |
prev C++20 |
Erstellt eine Kopie davon subrange , aber mit dem gespeicherten Iterator wurde der angegebene Abstand zurück verschoben. |
size C++20 |
Ruft die Anzahl der Elemente ab. |
Geerbt von view_interface |
Beschreibung |
back C++20 |
Rufen Sie das letzte Element ab. |
data C++20 |
Rufen Sie einen Zeiger auf das erste Element ab. |
front C++20 |
Rufen Sie das erste Element ab. |
operator[] C++20 |
Rufen Sie das Element an der angegebenen Position ab. |
operator bool C++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 subrange
hinaus gehen, wird der Iterator am Ende des subrange
Wä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
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 false
zurü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
:
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 subrange
gespeichert 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 subrange
Werts, 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 subrange
gespeichert 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, advance
z. B. wird die gemeldete Größe geändert.