Notitie
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen u aan te melden of de directory te wijzigen.
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen de mappen te wijzigen.
Bereikadapters maken een weergave (een van de weergaveklassen in de std::views
naamruimte) uit een bereik. U wordt aangeraden een adapter te gebruiken om weergaven te maken in plaats van de weergavetypen rechtstreeks te maken. De adapters zijn de beoogde manier om toegang te krijgen tot weergaven. Ze zijn eenvoudiger te gebruiken en in sommige gevallen efficiënter dan het rechtstreeks maken van exemplaren van de weergavetypen.
Een weergave is een lichtgewicht object dat verwijst naar elementen uit een bereik. Een weergave kan:
- Bestaan alleen uit bepaalde elementen uit een bereik.
- Vertegenwoordig een transformatie van elementen uit een bereik.
- Wees het omgekeerde van of alleen de eerste
n
elementen van een bereik. - Wees een combinatie van de voorgaande dingen.
Een weergave is goedkoop, O(1)
om te kopiëren, toe te wijzen en te vernietigen, ongeacht het aantal elementen. Bekijk het volgende voorbeeld:
// requires /std:c++20 or later
#include <ranges>
#include <vector>
#include <iostream>
int main()
{
std::vector<int> input = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
auto divisible_by_three = [](const int n) {return n % 3 == 0;};
auto square = [](const int n) {return n * n;};
auto x = input | std::views::filter(divisible_by_three)
| std::views::transform(square);
for (int i : x)
{
std::cout << i << ' ';
}
}
0 9 36 81
De eerste bereikadapter, filter
biedt een weergave die de elementen bevat input
die deelbaar zijn door drie. De andere bereikadapter, transform
neemt de weergave met de elementen deelbaar door drie en geeft een beeld van het vierkant van die elementen.
Wanneer een bereikadapter een weergave produceert, worden er geen kosten in rekening gebracht voor het transformeren van elk element in het bereik om die weergave te produceren. De kosten voor het verwerken van een element in de weergave worden alleen betaald wanneer u dat element opent.
Het maken van een weergave is de voorbereiding op het uitvoeren van werk in de toekomst. In het vorige voorbeeld resulteert het maken van de weergave niet in het vinden van alle elementen die deelbaar zijn door drie of het kwadrateren van die elementen. Er gebeurt alleen werk wanneer u toegang hebt tot een element in de weergave.
Elementen van een weergave zijn meestal de werkelijke elementen van het bereik dat wordt gebruikt om de weergave te maken. De weergave is meestal niet de eigenaar van de elementen; het verwijst alleen naar hen, met uitzondering van owning_view
. Als u een element wijzigt, wordt dat element in het bereik gewijzigd waaruit de weergave is gemaakt. In het volgende voorbeeld ziet u dit gedrag:
#include <algorithm>
#include <iostream>
#include <ranges>
int main()
{
int input[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
auto even = [](const int n) { return n % 2 == 0; };
auto x = input | std::views::filter(even); // create a view of the even elements from input
for (int &i : x)
{
std::cout << i << ' '; // 0 2 4 6 8 10
}
std::cout << '\n';
std::ranges::fill(x, 42); // changes the evens from input[] to 42
for (int &i : input) // demonstrates that the even elements in the range are modified
{
std::cout << i << ' '; // // 42 1 42 3 42 5 42 7 42 9 42
}
}
Bereikadapters komen in veel vormen voor. Er zijn bijvoorbeeld bereikadapters waarmee u een weergave kunt produceren door:
- Een ander bereik filteren op basis van een predicaat (
filter
). - De elementen in een bereik (
transform
) transformeren. - Een bereik splitsen (
split
).
Bereikadapters kunnen worden gekoppeld (samengesteld). Dat is waar de kracht en flexibiliteit van bereiken het meest duidelijk zijn. Door bereikadapters op te stellen, kunt u een kernprobleem oplossen met de vorige STL-algoritmen (Standard Template Library), namelijk dat ze niet gemakkelijk aan elkaar kunnen worden gekoppeld.
De volgende bereikadapters zijn beschikbaar in de std::views
naamruimte. De std::views
naamruimte is een handige alias voor std::ranges::views
.
Bereikadapter | Beschrijving |
---|---|
all
C++20- |
Maak een weergave die verwijst naar een bereik en de bijbehorende elementen. |
common
C++20- |
Maak een weergave met dezelfde iterator- en sentinel-typen uit een bereik dat dat niet doet. |
counted
C++20- |
Maak een weergave van de eerste n elementen van een bereik, beginnend vanaf de opgegeven locatie. |
drop
C++20- |
Maak een weergave vanuit een andere weergave, waarbij het opgegeven aantal elementen van de voorzijde wordt overgeslagen. |
drop_while
C++20- |
Maak een weergave die de elementen van een bereik bevat die na de voorloopelementen die overeenkomen met de opgegeven voorwaarde, worden verwijderd. |
elements
C++20- |
Maak een weergave van de geselecteerde index in elke tuple-achtige waarde in een bereik. |
empty
C++20- |
Maak een weergave die geen elementen bevat. |
filter
C++20- |
Maak een weergave die de elementen van een bereik bevat dat overeenkomt met de opgegeven voorwaarde. |
iota
C++20- |
Maak een weergave die een reeks toenemende waarden bevat. |
istream
C++20- |
Een weergave maken over de elementen van een stroom. |
join
C++20- |
Een weergave maken waarin alle elementen van meerdere bereiken in één weergave worden gecombineerd. |
keys
C++20- |
Maak een weergave van de eerste index in elke tuple-achtige waarde in een verzameling. |
lazy_split
C++20- |
Een weergave splitsen in subbereiken op basis van een scheidingsteken. |
reverse
C++20- |
Maak een weergave van de elementen van een bereik in omgekeerde volgorde. |
single
C++20- |
Een weergave maken die één element bevat. |
split
C++20- |
Een weergave splitsen in subbereiken op basis van een scheidingsteken. |
take
C++20- |
Een weergave van de eerste n elementen maken vanuit een andere weergave. |
take_while
C++20- |
Maak een weergave die de voorloopelementen van een bereik bevat dat overeenkomt met de opgegeven voorwaarde. |
transform
C++20- |
Een weergave van getransformeerde elementen maken vanuit een andere weergave. |
values
C++20- |
Maak een weergave van de tweede index in elke tuple-achtige waarde in een verzameling. |
In de vorige tabel wordt een bereikadapter meestal beschreven als het nemen van een bereik en het produceren van een weergave. Om precies te zijn, hebben bereikadapters een bereikargument dat een van de volgende opties accepteert:
- Het
cv-unqualified
typemodellenview
en het argument is een rvalue of kan worden gekopieerd. - Wanneer u het argument doorgeeft als een lvalue, moet het modelleren
range
en leven zolang de weergave. - Wanneer u het argument doorgeeft als een rvalue, zoals bij het aanroepen
owning_view
, moet het modellerenrange
enmovable
.
Bereikadapterfuncties zijn doorgaans functieobjecten, die eruitzien als functieoproepen en beperkingen afdwingen voor de typen die kunnen worden doorgegeven.
U kunt bereikadapters en het resultaat van pijpbewerkingen (|
) doorgeven aan code die functieobjecten verwacht. In het volgende voorbeeld wordt de weergave die de split
bereikadapter maakt, doorgegeven aan de transform
bereikadapter alsof deze wordt aangeroepen door een functieaanroep, omdat de transform
bereikadapter een functieobject is.
std::map<int, string> x = {{0, "Hello, world"}, {42, "Goodbye, world"}};
auto y = x | views::values | views::transform(views::split(' '));
// y is a range whose elements are ranges of whitespace-delimited strings from each value in x:
// {{"Hello", "world"}, {"Goodbye", "world"}}
all
Maak een weergave van alle elementen in een bereik.
template <ranges::viewable_range R>
constexpr ranges::view auto all(R&& rg) const noexcept;
Parameterwaarden
R
Het type van het onderliggende bereik.
rg
Het bereik waaruit u de weergave wilt maken.
Retourwaarde
- Als
rg
dit al een weergave is, wordt er een kopie vanrg
. - Als
rg
dit een niet-weergave lvalue is, wordt hiernaarref_view
verwezenrg
. (De levensduur van de weergave is gekoppeld aan de levensduur vanrg
.) - Als
rg
dit een niet-weergave rwaarde is, zoals een tijdelijk object, of het resultaat is van het doorgeven van het bereik aanstd::move
, eenowning_view
.
Hiermee std::views::all_t<decltype((rg))>
haalt u het type van de geretourneerde weergave op.
Opmerkingen
Deze bereikadapter is de beste manier om een bereik te converteren naar een weergave. Een van de redenen om een weergave van een bereik te maken, is om deze tegen lage kosten door te geven, als het bereik op waarde kan duur zijn.
Het verkrijgen van een weergave voor een bereik is een handig alternatief voor het doorgeven van een zwaargewicht bereik op waarde omdat weergaven goedkoop zijn om te maken, kopiëren en vernietigen. Een mogelijke uitzondering is owning_view
, een weergave die eigenaar is van het onderliggende bereik.
Over het algemeen heeft O(N)
het slechtste scenario voor het vernietigen van een weergave complexiteit voor het aantal elementen in het bereik. Zelfs als u kopieën van weergave met K
elementen vernietigtN
, is de totale complexiteit nog steeds O(N)
omdat het onderliggende bereik slechts eenmaal wordt vernietigd.
Voorbeeld: all
// requires /std:c++20 or later
#include <ranges>
#include <iostream>
#include <vector>
int main()
{
std::vector<int> v = {1,2,3,4,5,6,7,8,9,10};
auto myRefView = std::views::all(v); // create a ref_view of the vector
std::cout << myRefView.size() << '\n'; // 10
auto myOwningView = std::views::all(std::move(v)); // create an owning_view from a moved vector
std::cout << myRefView.size() << '\n'; // outputs 0 because myOwningView now owns the elements
std::cout << v.size() << '\n'; // outputs 0 because myOwningView now owns the elements
std::cout << myOwningView.size(); // 10
}
10
0
0
10
common
Maak een weergave met hetzelfde begin-iterator- en sentinel-type uit een bereik dat mogelijk niet.
template <ranges::viewable_range R>
constexpr ranges::view auto common(R&& rg) const noexcept;
Parameterwaarden
R
Het type van het onderliggende bereik.
rg
Het bereik waaruit u de weergave wilt maken.
Retourwaarde
-
views::all(rg)
alsrg
een bereik met hetzelfde iterator- en sentinel-type is. -
common_view(views::all(rg))
alsrg
er verschillende iterator- en sentinel-typen zijn.
Opmerkingen
Wanneer een API vereist dat de begin-iterator en end sentinel hetzelfde type hebben en de weergave die u gebruikt, niet voldoet aan die vereiste (of u weet niet of dit het geval is), gebruikt u deze bereikadapter om een common_view
. Het garandeert dat het type van de begin-iterator en het type van de end sentinel hetzelfde zijn.
Voorbeeld: common
// requires /std:c++20 or later
#include <ranges>
#include <iostream>
#include <numeric>
#include <list>
int main()
{
std::list<int> lst{1, 2, 3, 4, 5, 6, 7, 8, 9};
auto firstFive = std::views::take(lst, 5);
// firstFive.begin(), firstFive.end() have different types: counted_iterator versus default_sentinel
// auto r = std::accumulate(firstFive.begin(), firstFive.end(), 0); // Error: accumulate() requires firstFive.begin() and firstFive.end() types to be the same.
auto common = std::views::common(firstFive); // create a common_view that has the same begin/end iterator types
std::cout << std::accumulate(common.begin(), common.end(), 0); // Now you can call the API because the iterator types are the same. Outputs 15 (1+2+3+4+5)
}
15
counted
Maak een weergave van de eerste count
elementen van een bereik, beginnend vanaf de opgegeven locatie.
template<class Iterator>
constexpr auto counted(Iterator&& it, iter_difference_t<Iterator> count);
Parameterwaarden
DifferenceType
Het type van het aantal.
Iterator
Het type iterator.
count
Het aantal elementen dat in de weergave moet worden opgenomen. Moet niet-negatief zijn.
- Als
count == 0
, wordt er een legespan
waarde geretourneerd. - Als
count
het aantal elementen in het bereik groter is dan het aantal elementen, is het gedrag niet gedefinieerd.
it
Een iterator voor het element in het bereik om mee te beginnen. Het element waarnaar de iterator verwijst, wordt opgenomen in de gemaakte weergave.
Retourwaarde
Een span
wordt geretourneerd als it
dit een is contiguous_iterator
voor matrices, vectoren en andere containers die hun elementen aaneengesloten opslaan. Anders wordt er een subrange
geretourneerd.
Opmerkingen
De opgenomen elementen zijn [it, count)
.
Nadat de weergave is gemaakt, blijft het aantal elementen in de weergave hetzelfde, zelfs als het bereik dat is gemaakt op basis van wijzigingen. Als het onderliggende bereik echter verandert, kan het openen van elementen in de weergave leiden tot niet-gedefinieerd gedrag.
Voorbeeld: counted
// requires /std:c++20 or later
#include <algorithm>
#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
drop
Maak een weergave die de eerste n elementen van een bereik uitsluit.
1) template<ranges::viewable_range R>
constexpr ranges::view auto drop(R&& rg, ranges::range_difference_t<R> count);
2) template<class DifferenceType>
constexpr /* range closure object */ drop(DifferenceType&& count);
Parameterwaarden
DifferenceType
Het type dat het aantal elementen beschrijft dat moet worden overgeslagen.
count
Het aantal elementen dat van de voorzijde moet rg
worden verwijderd. Moet niet-negatief zijn.
- Als
count == 0
, worden alle elementen inrg
geretourneerd. - Als
count
het aantal elementen groter is dan het aantal elementenrg
, wordt een lege weergave geretourneerd.
R
Het type bereik.
rg
Het bereik dat wordt gebruikt om de weergave te maken.
Retourwaarde
Een weergave van het onderliggende bereik, waarbij het opgegeven aantal elementen van de voorzijde is verwijderd.
Als u meer elementen opgeeft die moeten worden verwijderd dan in het onderliggende bereik, wordt er een empty_view
geretourneerd.
De geretourneerde weergave is doorgaans, maar niet altijd, een specialisatie van drop_view
. Dat wil zeggen:
- Als
V
een specialisatie vanempty_view
, of is een specialisatie vanspan
,basic_string_view
, ofiota_view
subrange
dat zowelrandom_access_range
ensized_range
, het resultaat is een specialisatie vanV
. - Anders is het resultaat een
drop_view
.
Opmerkingen
Nadat de weergave is gemaakt, blijft het aantal elementen in de weergave hetzelfde, zelfs als de weergave is gemaakt op basis van wijzigingen. Als de onderliggende weergave echter verandert, kan het openen van elementen in de geretourneerde weergave leiden tot niet-gedefinieerd gedrag.
drop
is het tegenovergestelde van take
.
De code die eerder wordt weergegeven als '2)' kan worden gebruikt met de syntaxis van de pijp: collection | drop(5)
. Of kan worden gebruikt met syntaxis van functieoproep: drop(collection, 5)
of drop(5)(collection)
.
Voorbeeld: drop
// requires /std:c++20 or later
#include <ranges>
#include <iostream>
#include <vector>
int main()
{
std::vector<int> v{1, 2, 3, 4, 5};
auto newView = std::views::drop(v, 3);
for (auto e : newView) // 4 5
{
std::cout << e << ' ';
}
std::cout << '\n';
auto numbers = std::views::iota(0) | std::views::take(10); // build a view of 10 integers
auto latterHalf = numbers | std::views::drop(5);
for (auto i : latterHalf)
{
std::cout << i << ' '; // 5 6 7 8 9
}
}
4 5
5 6 7 8 9
drop_while
Maak een weergave die de elementen van een bereik bevat die na de voorloopelementen die overeenkomen met de opgegeven voorwaarde, worden verwijderd.
1) template<ranges::viewable_range R, class P>
constexpr ranges::view auto drop_while(R&& rg, P&& predicate);
2) template<class P>
constexpr /*range adaptor closure*/ drop_while(P&& predicate);
Parameterwaarden
R
Het type bereik.
predicate
De voorwaarden die bepalen welke voorloopelementen uit het bereik moeten worden verwijderd.
rg
Het onderliggende bereik waaruit u de weergave wilt maken.
Retourwaarde
Een drop_while_view
die bestaat uit de elementen die behouden blijven wanneer de voorloopelementen die overeenkomen met het predicaat worden verwijderd.
Opmerkingen
Stopt met het verwijderen van elementen vanaf rg
zodra het predicaat terugkeert false
.
drop_while
is het tegenovergestelde van take_while
.
De code die eerder wordt weergegeven als '2)' kan worden gebruikt met de syntaxis van de pijp: collection | drop_while(predicate)
. Of kan worden gebruikt met syntaxis van functieoproep: drop_while(collection, predicate)
of drop_while(predicate)(collection)
.
Voorbeeld: drop_while
// requires /std:c++20 or later
#include <ranges>
#include <iostream>
#include <vector>
void print(auto&& v)
{
for (auto&& x : v)
{
std::cout << x << ' ';
}
std::cout << '\n';
}
int main()
{
std::vector<int> v{ 0, 1, 2, 3, -4, 5, 6 };
auto myView = std::views::drop_while(
v,
[](int i) {return i >= 0; });
print(myView); // -4 5 6
auto myView2 = v | std::views::drop_while(
[](int i) {return i < 5; });
print(myView2); // 5 6
}
-4 5 6
5 6
elements
Maak een elements_view
, een weergave van de geselecteerde index in elke tuple-achtige waarde in een bereik. Als u bijvoorbeeld een bereik met std::tuple<string, int>
waarden hebt, maakt u een elements_view
van alle string
elementen van elke tuple.
template<ranges::viewable_range R, size_t N>
constexpr ranges::view auto elements<N>(R&& rg);
Parameterwaarden
N
De index van het element dat moet worden geselecteerd uit elke tuple-achtige waarde die in de weergave moet worden opgenomen.
R
Het type van het onderliggende bereik.
rg
Het bereik van tuple-achtige waarden waaruit u de weergave wilt maken.
Retourwaarde
Een elements_view
die bestaat uit de geselecteerde index in elke tuple-achtige waarde in een verzameling.
Voorbeeld: elements
// requires /std:c++20 or later
#include <ranges>
#include <iostream>
#include <map>
#include <string>
int main()
{
std::map<std::string, int> cpp_standards
{
{"C++98", 1998},
{"C++03", 2003},
{"C++11", 2011},
{"C++14", 2014},
{"C++17", 2017},
{"C++20", 2020}
};
// Create an elements_view of all the string elements from each tuple
for (int const year : std::views::elements<1>(cpp_standards))
{
std::cout << year << ' '; // 2003 2011 2014 2017 1998 2020
}
std::cout << '\n';
// Another way, using |: create an elements_view of all the int elements from each tuple
for (auto&& name : cpp_standards | std::views::elements<0>)
{
std::cout << name << ' '; // C++03 C++11 C++14 C++17 C++98 c++20
}
}
2003 2011 2014 2017 1998 2020
C++03 C++11 C++14 C++17 C++98 c++20
empty
Maak een empty_view
, een weergave die geen elementen bevat.
template<class T>
inline constexpr empty_view<T> empty{};
Parameterwaarden
T
Het type elementen in de weergave. De weergave heeft een elementtype nodig, ook al zijn er geen elementen.
Retourwaarde
Een empty_view
.
Opmerkingen
Een empty_view
kan handig zijn wanneer u code aanroept die een weergave vereist, maar geen van de elementen hoeft te verwerken.
Voorbeeld: empty
// requires /std:c++20 or later
#include <ranges>
#include <iostream>
int main()
{
auto anEmptyView = std::views::empty<int>;
bool isNotEmpty = (bool)anEmptyView;
std::cout << boolalpha << isNotEmpty << "\n"; // false
}
false
filter
Maak een weergave die de elementen van een bereik bevat dat overeenkomt met de opgegeven voorwaarde.
1) template<ranges::viewable_range R, class P>
requires {filter_view(forward<R>(rg), forward<P>(predicate));}
constexpr ranges::view auto filter(R&& rg, P&& predicate);
2) template<class P>
constexpr /*range adaptor closure*/ filter(P&& predicate);
Parameterwaarden
P
Het type predicaat.
predicate
De voorwaarden die bepalen welke elementen in het bereik moeten worden bewaard.
R
Het type van het onderliggende bereik.
rg
Het bereik waaruit u de weergave wilt maken.
Retourwaarde
Een filter_view
die de elementen van een bereik bevat dat overeenkomt met het predicaat.
Opmerkingen
Als u een pijp gebruikt filter
en transform
samen met een pijp |
gebruikt, doet u het filter
eerste zodat u transform
alleen de elementen die u wilt behouden.
De code die eerder wordt weergegeven als '2)' kan worden gebruikt met de syntaxis van de pijp: collection | filter(predicate)
. Of kan worden gebruikt met syntaxis van functieoproep: filter(collection, predicate)
of filter(predicate)(collection)
.
Voorbeeld: filter
// requires /std:c++20 or later
#include <ranges>
#include <iostream>
#include <vector>
void print(auto&& v)
{
for (auto&& x : v)
{
std::cout << x << ' ';
}
std::cout << '\n';
}
int main()
{
std::vector<int> v{0, 1, 2, 3, -4, 5, 6};
auto myView = std::views::filter(v, [](int i) {return i < 5; });
print(myView); // 0 1 2 3 -4
auto myView2 = v | std::views::filter([](int i) {return i < 5; }); // pipe syntax
print(myView2); // 0 1 2 3 -4
}
0 1 2 3 -4
0 1 2 3 -4
iota
Maak een weergave die een reeks toenemende waarden bevat. De reeks kan worden gebonden of niet.
template<class V>
constexpr ranges::view auto iota(V&& startValue); // create an unbounded sequence of incrementing values
template<class V, class E>
constexpr ranges::view auto iota(V&& startValue, E&& endValue); // create a bounded sequence of incrementing values
Parameterwaarden
E
Het type van de eindwaarde.
S
Het type van de beginwaarde.
startValue
De eerste waarde in de reeks.
endValue
Deze waarde is één achter de laatste waarde die zich in de reeks bevindt. Genereert bijvoorbeeld std::views::iota(0, 5)
een weergave met de waarden 0,1,2,3,4
.
Retourwaarde
Een iota_view
reeks toenemende waarden.
Opmerkingen
Voor een niet-gebonden reeks is het gedrag niet gedefinieerd nadat de maximumwaarde van het gegevenstype is bereikt.
Voorbeeld: iota
// requires /std:c++20 or later
#include <ranges>
#include <iostream>
void print(auto&& v)
{
for (auto&& x : v)
{
std::cout << x << ' ';
}
std::cout << '\n';
}
int main()
{
// create an iota view with its range adaptor (preferred)
print(std::views::iota(0, 5)); // outputs 0 1 2 3 4
// create an iota_view class directly
std::ranges::iota_view letters{'a', 'f'};
print(letters); // a b c d e
}
0 1 2 3 4
a b c d e
istream
Een weergave maken over de elementen van een stroom.
template <class Val>
views::istream<Val>(str);
Parameterwaarden
str
Een stroomobject. Het type is afgeleid van een specialisatie van std::basic_istream
.
Val
Het type elementen dat uit de stroom moet worden geëxtraheerd.
Retourwaarde
Deze bereikadapter is gelijk aan ranges::basic_istream_view<Val, typename U::char_type, typename U::traits_type>(str)
, waar U
is het type str
.
Voorbeeld: istream
// requires /std:c++20 or later
#include <ranges>
#include <iostream>
#include <sstream>
#include <vector>
int main()
{
std::istringstream doubles{"1.1 2.2 3.3 4.4 5.5"};
for (const auto& elem : std::views::istream<double>(doubles))
{
std::cout << elem << ' '; // 1.1 2.2 3.3 4.4 5.5
}
}
1.1 2.2 3.3 4.4 5.5
join
Een weergave maken waarin alle elementen van meerdere bereiken in één weergave worden gecombineerd.
1) template <ranges::viewable_range R>
[[nodiscard]] constexpr ranges::view auto join(R&& rg) const noexcept;
2) inline constexpr /*range adaptor closure*/ join();
Parameterwaarden
R
Het type van het onderliggende bereik.
rg
Het bereik waaruit u de weergave wilt maken.
Retourwaarde
Een join_view
met de elementen van alle bereiken in het onderliggende bereik.
Voorbeeld: join
#include <iostream>
#include <vector>
#include <ranges>
#include <string>
int main()
{
// a range of two ranges
std::vector<std::string> rangeOfRanges[2]{{"C++20", "contains:"}, {"ranges", "modules", "concepts & more."}};
for (const auto& elem : std::views::join(rangeOfRanges))
{
std::cout << elem << ' ';
}
}
C++20 contains: ranges modules concepts & more.
Opmerkingen
De code die eerder wordt weergegeven als '2)' kan worden gebruikt met de syntaxis van de pijp: collection | join
. Of kan worden gebruikt met de syntaxis van de functie-aanroep: join(collection)
.
keys
Maak een keys_view
van de eerste index in elke tuple-achtige waarde in een verzameling. Dit is handig voor het extraheren van sleutels uit associatieve containers. Als u bijvoorbeeld een bereik hebt std::tuple<string, int>
, maakt u een weergave die bestaat uit alle string
elementen van elke tuple.
template <ranges::viewable_range R>
constexpr auto keys(R&& rg);
Parameterwaarden
R
Het type van het onderliggende bereik.
Retourwaarde
Een keys_view
die bestaat uit de eerste index in elke tuple-achtige waarde in het bereik.
Voorbeeld: keys
// requires /std:c++20 or later
#include <ranges>
#include <iostream>
#include <map>
#include <string>
#include <vector>
int main()
{
// ========== extract keys from a map
std::map<std::string, int> cpp_standards
{
{"C++98", 1998},
{"C++03", 2003},
{"C++11", 2011},
{"C++14", 2014},
{"C++17", 2017},
{"C++20", 2020}
};
// Extract all of the keys from the map
for (std::string standards : std::views::keys(cpp_standards))
{
std::cout << standards << ' '; // C++03 C++11 C++14 C++17 C++98 C++20
}
std::cout << '\n';
// ========== Extract keys from a pair
std::vector<std::pair<std::string, int>> windows
{
{"Windows 1.0", 1985},
{"Windows 2.0", 1987},
{"Windows 3.0", 1990},
{"Windows 3.1", 1992},
{"Windows NT 3.1", 1993},
{"Windows 95", 1995},
{"Windows NT 4.0", 1996},
{"Windows 95", 1995},
{"Windows 98", 1998},
{"Windows 1.0", 1985},
{"Windows 2000", 2000}
};
// Another way to call the range adaptor is by using '|'
for (std::string version : windows | std::views::keys)
{
std::cout << version << ' '; // Windows 1.0 Windows 2.0 Windows 3.0 ...
}
}
C++03 C++11 C++14 C++17 C++98 C++20
Windows 1.0 Windows 2.0 Windows 3.0 Windows 3.1 Windows NT 3.1 Windows 95 Windows NT 4.0 Windows 95 Windows 98 Windows 1.0 Windows 2000
lazy_split
Splits een bereik in subbereiken op basis van een scheidingsteken. Het scheidingsteken kan één element of een weergave van elementen zijn.
1) template<viewable_range R, class Pattern>
constexpr view auto lazy_split(R&& rg, Pattern&& delimiter);
2) template<class Pattern>
constexpr /*range adaptor closure*/ lazy_split(Pattern&& delimiter);
Parameterwaarden
delimiter
Eén waarde of een reeks waarden die aangeven waar het bereik moet worden gesplitst.
Pattern
Het type scheidingsteken.
R
Het type bereik dat moet worden gesplitst.
rg
Het bereik dat moet worden gesplitst.
Retourwaarde
Een lazy_split_view
met een of meer subbereiken en is het resultaat van het splitsen van het oorspronkelijke bereik op delimiter
.
Opmerkingen
Het scheidingsteken maakt geen deel uit van het resultaat. Als u bijvoorbeeld het bereik 1,2,3
splitst op de waarde 2
, krijgt u twee subbereiken: 1
en 3
.
Een gerelateerde adapter is split
. De belangrijkste verschillen tussen split_view
en lazy_split_view
zijn:
Bekijk | Kan een const bereik splitsen |
Bereik-iterator |
---|---|---|
split_view |
Nee | Ondersteunt forward_range of hoger |
lazy_split_view |
ja |
input_range of hoger |
Liever split_view
omdat het efficiënter is, tenzij u een bereik moet splitsen dat is const
.
De code die eerder wordt weergegeven als '2)' kan worden gebruikt met de syntaxis van de pijp: collection | lazy_split(delimiter)
. Of kan worden gebruikt met syntaxis van functieoproep: lazy_split(collection, delimiter)
of lazy_split(delimiter)(collection)
.
Voorbeeld: lazy_split
// requires /std:c++20 or later
#include <ranges>
#include <iostream>
#include <vector>
int main()
{
std::vector<int> rg{1, 2, 3, 1, 2, 3, 4, 5, 6};
// split on a single element
for (const auto& sub : rg | std::views::split(3))
{
// outputs:
// 1 2
// 1 2
// 4 5 6
for (const auto& elem : sub)
{
std::cout << elem << ' ';
}
std::cout << '\n';
}
// split on a sequence of elements
int delimiters[] = {2, 3};
for (const auto& subrange : std::views::split(rg, delimiters))
{
// outputs 1 1 4 5 6
for (auto& i : subrange)
{
std::cout << i << " ";
}
}
}
1 2
1 2
4 5 6
1 1 4 5 6
reverse
Maak een weergave van de elementen van een bereik in omgekeerde volgorde.
1) template<viewable_range R>
constexpr ranges::view auto reverse(R&& rg);
2) inline constexpr /*range adaptor closure*/ reverse();
Parameterwaarden
R
Het type van het onderliggende bereik dat u wilt omkeren.
rg
Het bereik om terug te keren.
Retourwaarde
Een weergave die de elementen van het onderliggende bereik in omgekeerde volgorde weergeeft. De geretourneerde weergave is doorgaans, maar niet altijd, een specialisatie van reverse_view
. Dat wil zeggen:
- Als
V
dit een specialisatiereverse_view
is, is het resultaat de onderliggende weergave van het argument. Een dubbele omkering is een no-op (geen bewerking). - Als
V
het formuliersubrange<reverse_iterator<I>, reverse_iterator<I>>
is, is het resultaat eensubrange
van de uitgepakte iterators. Een dubbele omkering is een no-op. - Anders is het resultaat een
reverse_view
.
Opmerkingen
De code die eerder wordt weergegeven als '2)' kan worden gebruikt met de syntaxis van de pijp: collection | reverse
. Of kan worden gebruikt met de syntaxis van de functie-aanroep: reverse(collection)
.
Voorbeeld: reverse
// 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 };
auto rv = v | std::views::reverse; // using the pipe syntax
for (auto &&e : rv) // outputs 6 5 -4 3 2 1 0
{
std::cout << e << ' ';
}
std::cout << '\n';
// using the range adaptor without using the pipe syntax
auto rv2 = std::views::reverse(v);
for (auto &&e : rv2) // outputs 6 5 -4 3 2 1 0
{
std::cout << e << ' ';
}
}
6 5 -4 3 2 1 0
6 5 -4 3 2 1 0
single
Maak een single_view
, een weergave die één element bevat.
template<class T>
constexpr ranges::view auto single(T&& t);
Parameterwaarden
T
Het type element in de weergave.
t
De waarde van het element dat in de weergave moet worden opgeslagen.
Retourwaarde
Een single_view
met t
.
Opmerkingen
Deze weergave is handig voor testdoeleinden, voor het aanroepen van code die moet worden geleverd met een weergave met ten minste één element erin.
Voorbeeld: single
// requires /std:c++20 or later
#include <ranges>
#include <string>
#include <tuple>
#include <iostream>
int main()
{
auto sv = std::views::single(7);
std::cout << sv.front() << " " << *sv.data() << "\n"; // 7 7
auto sv2 = std::views::single(<std::tuple<double, std::string>{6502, "8-bit"});
std::cout << std::get<0>(sv2[0]) << " " << std::get<1>(sv2[0]) << "\n"; // 6502 8-bit
}
7 7
6502 8-bit
split
Een weergave splitsen in subbereiken op basis van een scheidingsteken. Het scheidingsteken kan één element of een reeks elementen zijn.
1) template<viewable_range R, class Pattern>
constexpr view auto split(R&& rg, Pattern&& delimiter);
2) template<class Pattern>
constexpr /*range adaptor closure*/ split(Pattern&& delimiter);
Parameterwaarden
delimiter
Eén waarde of een reeks waarden die aangeven waar het bereik moet worden gesplitst.
Pattern
Het type scheidingsteken.
R
Het type van het onderliggende bereik dat moet worden gesplitst.
rg
Het bereik dat moet worden gesplitst.
Retourwaarde
Een split_view
met een of meer subbereiken.
Opmerkingen
Het scheidingsteken maakt geen deel uit van het resultaat. Als u bijvoorbeeld het bereik 1,2,3
splitst op de waarde 2
, krijgt u twee subbereiken: 1
en 3
.
Een gerelateerde adapter is lazy_split
. De belangrijkste verschillen tussen split_view
en lazy_split_view
zijn:
Bekijk | Kan een const bereik splitsen |
Bereiktype |
---|---|---|
split_view |
Nee | Ondersteunt forward_range of hoger |
lazy_split_view |
ja | Ondersteunt input_range of hoger |
Liever split_view
omdat het efficiënter is, tenzij u een bereik moet splitsen dat is const
.
De code die eerder wordt weergegeven als '2)' kan worden gebruikt met de syntaxis van de pijp: collection | split(delimiter)
. Of kan worden gebruikt met syntaxis van functieoproep: split(collection, 5)
of split(5)(collection)
.
Voorbeeld: split
// requires /std:c++20 or later
#include <ranges>
#include <vector>
#include <iostream>
int main()
{
std::vector<int> rg{ 1, 2, 3, 1, 2, 3, 4, 5, 6 };
// split on a single element, 3
for (const auto& sub : rg | std::views::split(3))
{
// This prints out:
// 1,2
// 4,5,6
for (const auto& elem : sub)
{
std::cout << elem << ' ';
}
std::cout << '\n';
}
// split on a sequence of elements, 2,3
int delimiters[] = {2, 3};
for (const auto& subrange : std::views::split(rg, delimiters))
{
// outputs 1 1 4 5 6
for (auto& i : subrange)
{
std::cout << i << " ";
}
}
}
1 2
1 2
4 5 6
1 1 4 5 6
take
Maak een weergave die het opgegeven aantal elementen bevat dat afkomstig is van de voorkant van een bereik.
1) template<ranges::viewable_range R>
constexpr ranges::view auto take(R&& rg, ranges::range_difference_type<R> count);
2) template<class DifferenceType>
constexpr /*range adaptor closure*/ take(DifferenceType&& count);
Parameterwaarden
R
Het type van het onderliggende bereik.
rg
Het bereik waaruit u de weergave wilt maken.
count
Het aantal elementen dat van de voorzijde moet rg
worden overgenomen.
Retourwaarde
De geretourneerde weergave is doorgaans, maar niet altijd, een specialisatie van take_view
. Specifiek:
- Als
V
een specialisatie vanempty_view
, of is een specialisatie vanspan
,basic_string_view
, ofiota_view
subrange
dat zowelrandom_access_range
ensized_range
, het resultaat is een specialisatie vanV
. - Anders is het resultaat een
take_view
.
Opmerkingen
Als u meer elementen opgeeft die moeten worden gebruikt dan aanwezig rg
is, worden alle elementen gebruikt.
take
is het tegenovergestelde van drop
.
De code die eerder wordt weergegeven als '2)' kan worden gebruikt met de syntaxis van de pijp: collection | take(5)
. Of kan worden gebruikt met syntaxis van functieoproep: take(5, collection)
of take(5)(collection)
.
Voorbeeld: take
// requires /std:c++20 or later
#include <ranges>
#include <iostream>
#include <string>
#include <vector>
int main()
{
std::string s{ "abcdefg" };
auto myView = std::views::take(s, 3);
for (auto c : myView)
{
std::cout << c << ' '; // a b c
}
std::cout << std::endl;
for (auto c : s | std::views::take(3)) // pipe syntax
{
std::cout << c << ' '; // a b c
}
}
a b c
a b c
take_while
Maak een weergave die de voorloopelementen van een bereik bevat dat overeenkomt met de opgegeven voorwaarde.
1) template<ranges::viewable_range R, class P>
constexpr ranges::view auto take_while(R&& rg, P&& predicate);
2) template<class P>
constexpr /*range adaptor closure*/ take_while(P&& predicate);
Parameterwaarden
P
Het type predicaat.
predicate
De voorwaarden die bepalen welke voorloopelementen uit het bereik moeten worden gekopieerd.
R
Het type van het onderliggende bereik.
rg
Het bereik waaruit u de weergave wilt maken.
Retourwaarde
Een take_while_view
die bestaat uit de eerste count
elementen die voldoen aan de opgegeven criteria in het bereik.
Opmerkingen
Stopt met het nemen van elementen nadat rg
het predicaat terugkeert false
of het bereik geen elementen meer bevat.
take_while
is het tegenovergestelde van drop_while
.
De code die eerder wordt weergegeven als '2)' kan worden gebruikt met de syntaxis van de pijp: collection | take_while(pred)
. Of kan worden gebruikt met syntaxis van functieoproep: take_while(collection, pred)
of take_while(pred)(collection)
.
Voorbeeld: take_while
// requires /std:c++20 or later
#include <ranges>
#include <iostream>
#include <vector>
void print(auto&& v)
{
for (auto&& x : v)
{
std::cout << x << ' ';
}
std::cout << '\n';
}
int main()
{
std::vector<int> v{ 0, 1, 2, 3, -4, 5, 6 };
auto myView = std::views::take_while(
v, [](int i) {return i >= 0; });
print(myView); // 0 1 2 3
print(v | std::views::take_while( // 0 1 2 3 -4
[](int i) {return i < 5; })); // pipe syntax
}
0 1 2 3
0 1 2 3 -4
transform
Maak een weergave van elementen, die elk een transformatie is van een element in het opgegeven bereik.
1) template<viewable_range R, class F>
constexpr ranges::view auto transform(R&& rg, F&& fun);
2) template<class F>
constexpr /*range adaptor closure*/ transform(F&& fun);
Parameterwaarden
F
Het type van het functieobject om de elementen te transformeren.
R
Het type van het onderliggende bereik.
fun
De functie waarmee de elementen worden getransformeerd.
rg
Het bereik waaruit u de weergave wilt maken.
Retourwaarde
Een transform_view
die de getransformeerde elementen van rg
.
Opmerkingen
In het belang van efficiëntie, wanneer u opstelt filter
en transform
, doet u de filter
eerste, zodat u transform
alleen de elementen die u wilt behouden.
De code die eerder wordt weergegeven als '2)' kan worden gebruikt met de syntaxis van de pijp: collection | transform(fun)
. Of kan worden gebruikt met syntaxis van functieoproep: transform(collection, fun)
of transform(fun)(collection)
.
Voorbeeld: transform
// requires /std:c++20 or later
#include <ranges>
#include <iostream>
#include <vector>
void print(auto&& v)
{
for (auto&& x : v)
{
std::cout << x << ' ';
}
std::cout << '\n';
}
int main()
{
std::vector<int> v{0, 1, 2, 3, -4, 5, 6};
auto myView = std::views::transform(v, [](int i) {return i * 2; });
print(myView); // 0 2 4 6 -8 10 12
print(v | std::views::transform( // 0 2 4 6 -8 10 12
[](int i) {return i * 2; })); // pipe syntax
}
0 2 4 6 -8 10 12
0 2 4 6 -8 10 12
values
Maak een values_view
index die bestaat uit de tweede index in elke tuple-achtige waarde in een verzameling. Dit is handig voor het maken van een weergave van de waarden in een associatieve container. Als u bijvoorbeeld een bereik met std::tuple<string, int>
waarden hebt, maakt u een weergave die bestaat uit alle int
elementen van elke tuple.
template <ranges::viewable_range R>
constexpr ranges::view auto values(R&& rg);
Parameterwaarden
R
Het type van het onderliggende bereik.
rg
Het onderliggende bereik van tuple-achtige waarden.
Retourwaarde
Een values_view
gebouwd van de tweede index in elke tuple-achtige waarde in het bereik.
Voorbeeld: values
// requires /std:c++20 or later
#include <ranges>
#include <iostream>
#include <map>
#include <string>
#include <vector>
int main()
{
// ========== working with a map
std::map<std::string, int> cpp_standards
{
{"C++98", 1998},
{"C++03", 2003},
{"C++11", 2011},
{"C++14", 2014},
{"C++17", 2017},
{"C++20", 2020}
};
// Extract all of the years from the map
for (int years : std::views::values(cpp_standards))
{
std::cout << years << ' '; // 2003 2011 2014 2017 1998 2020
}
std::cout << '\n';
// ========== working with pairs
std::vector<std::pair<std::string, int>> windows
{
{"Windows 1.0", 1985},
{"Windows 2.0", 1987},
{"Windows 3.0", 1990},
{"Windows 3.1", 1992},
{"Windows NT 3.1", 1993},
{"Windows 95", 1995},
{"Windows NT 4.0", 1996},
{"Windows 95", 1995},
{"Windows 98", 1998},
{"Windows 1.0", 1985},
{"Windows 2000", 2000}
};
// Another way to call the range adaptor by using '|'
// Create a values_view that contains the year from each pair
for (int years : windows | std::views::values)
{
std::cout << years << ' '; // 1985 1987 1990 1992 ...
}
}
2003 2011 2014 2017 1998 2020
1985 1987 1990 1992 1993 1995 1996 1995 1998 1985 2000
Aliassen van bereikadaptertypen
all_t
Geeft het type weergave weer dat all
wordt geretourneerd.
template <ranges::viewable_range R>
using all_t = decltype(views::all(std::declval<R>()));
Parameterwaarden
R
Het type van het onderliggende bereik.
Retourwaarde
Het type weergave dat all
als resultaat geeft: decltype(views::all(std::declval<R>()))
.
Voorbeeld: all_t
#include <ranges>
#include <iostream>
#include <vector>
int main()
{
std::vector<int> v = {1,2,3,4,5,6,7,8,9,10};
auto myView = std::views::all(v);
std::views::all_t<decltype((v))> &viewType = myView;
}