Not
Åtkomst till denna sida kräver auktorisation. Du kan prova att logga in eller byta katalog.
Åtkomst till denna sida kräver auktorisation. Du kan prova att byta katalog.
En vy är ett enkelt intervall som refererar till element som den inte äger (förutom owning_view). En vy baseras vanligtvis på ett annat intervall och ger ett annat sätt att titta på den, antingen genom att transformera eller filtrera den. Är till exempel std::views::filter en vy som använder de villkor som du anger för att välja element från ett annat intervall.
När du kommer åt elementen i en vy görs det "lazily" så att arbetet bara utförs när du får ett element. Detta gör det möjligt att kombinera, eller skriva, vyer utan prestandastraff.
Du kan till exempel skapa en vy som bara innehåller de jämna elementen från ett intervall och sedan transformera dem genom att placera dem i kvart. Arbetet med att filtrera och transformera görs endast för de element som du kommer åt, och endast när du kommer åt dem.
En vy kan kopieras, tilldelas och förstöras i konstant tid oavsett hur många element den innehåller. Det beror på att en vy inte äger de element som den refererar till, så den behöver inte göra en kopia. Det är därför du kan skapa vyer utan prestandastraff.
Du skapar vanligtvis en vy med hjälp av en intervalladapter. Intervalladapter är det avsedda sättet att skapa en vy, är enklare att använda än att instansiera vyklasserna direkt och är ibland mer effektiva än att instansiera vyklasserna direkt. Vyklasserna exponeras direkt om du behöver skapa en egen anpassad vytyp baserat på en befintlig vytyp.
Här är ett kort exempel på hur du skapar en vy över kvadraterna för de element som är delbara med tre i en vektor:
// 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
}
}
0 9 36 81
Om du använder en vy efter det intervall som den baseras på ändras kan det leda till odefinierat beteende. En baserad på en vektor bör till exempel reverse_view inte återanvändas om du lägger till eller tar bort element från den underliggande vektorn. Om du ändrar den underliggande vektorn ogiltigförklaras containerns end iterator, inklusive kopian av iteratorn som vyn kan ha gjort.
Eftersom vyer är billiga att skapa bör du vanligtvis återskapa en vy om du ändrar det underliggande intervallet. I följande exempel visas hur du lagrar en visningspipeline i en variabel så att du kan återanvända den.
// requires /std:c++20 or later
#include <iostream>
#include <ranges>
#include <vector>
#include <list>
#include <string_view>
#include <algorithm>
template<typename rangeType>
void show(std::string_view msg, rangeType r)
{
std::cout << msg;
std::ranges::for_each(r,
[](auto e)
{
std::cout << e << ' ';
});
std::cout << '\n';
}
int main()
{
std::vector v{ 1, 2, 3, 4 };
show("v: ", v);
// You can save a view pipeline
auto rev3 = std::views::take(3) | std::views::reverse;
show("v | rev3: ", v | rev3); // 3 2 1
v.insert(v.begin(), 0); // v = 0 1 2 3 4
show("v: ", v);
// Because modifying the vector invalidates its iterators, rebuild the view.
// We are reusing the view pipeline we saved earlier
show("v | rev3(v): ", rev3(v));
}
v: 1 2 3 4
v | rev3: 3 2 1
v: 0 1 2 3 4
v | rev3(v): 2 1 0
Följande vyklasser definieras i std::ranges namnområdet.
| Utsikt | Beskrivning |
|---|---|
basic_istream_view
C++20 |
En vy över efterföljande element från en indataström. Specialiseringar inkluderar istream_view och wistream_view. |
common_view
C++20 |
Anpassar en vy som har olika iterator-/sentinel-typer till en vy med samma iterator-/sentinel-typer. |
drop_view
C++20 |
Skapas från en annan vy och hoppar över de första count elementen. |
drop_while_view
C++20 |
Skapas från en annan vy och hoppar över inledande element så länge ett predikat finns. |
elements_view
C++20 |
En vy över det valda indexet i varje tuppeln-liknande värde i en samling. Om du till exempel får ett intervall med std::tuple<string, int> värden skapar du en vy som består av alla string element från varje tuppeln. |
empty_view
C++20 |
En vy utan element. |
filter_view
C++20 |
Filtrerar bort element i ett intervall som inte matchar ett predikat. |
iota_view
C++20 |
En genererad vy som innehåller en sekvens med inkrementella värden. |
join_view
C++20 |
Kombinerar alla element i flera intervall till en enda vy. |
keys_view
C++20 |
En vy över det första indexet i varje tuppeln-liknande värde i en samling. Om du till exempel får ett värdeintervall std::tuple<string, int> skapar du en vy som består av elementen string från varje tuppeln. |
lazy_split_view
C++20 |
Delar upp en vy i underordningar baserat på en avgränsare. |
owning_view
C++20 |
Tar ägarskapet för elementen från ett annat intervall. |
ref_view
C++20 |
En vy som refererar till de element som tillhör ett annat intervall. |
reverse_view
C++20 |
Visar elementen i ett intervall i omvänd ordning. |
single_view
C++20 |
En vy som bara innehåller ett element. |
split_view
C++20 |
Delar upp en vy i underordningar baserat på en avgränsare. |
subrange
C++20 |
En vy över en del av elementen i ett intervall, som definieras av en start-iterator och en sentinel. |
take_view
C++20 |
Innehåller det angivna antalet element som tagits framifrån ett intervall. |
take_while_view
C++20 |
Innehåller de inledande elementen i ett intervall som matchar det angivna predikatet. |
transform_view
C++20 |
En vy över en underliggande sekvens efter att en transformeringsfunktion har tillämpats på varje element. |
values_view
C++20 |
En vy över det andra indexet i varje tuppeln-liknande värde i en samling. Om du till exempel får ett värdeintervall std::tuple<string, int> skapar du en vy som består av elementen int från varje tuppeln. |
Många av dessa klasser har motsvarande intervalladapter i namnområdet std::views som skapar instanser av dem. Använd en adapter för att skapa en vy i stället för att skapa vyklasser direkt. Intervalladapterarna är det avsedda sättet att skapa vyer, är enklare att använda och är i vissa fall mer effektiva.
Visa klassegenskaper
Varje vyklassavsnitt har ett avsnitt om egenskaper efter syntaxavsnittet. Avsnittet Egenskaper har följande poster:
Intervalladapter: En länk till intervalladaptern som skapar vyn. Du använder vanligtvis en intervalladapter för att skapa en vy i stället för att skapa en vyklass direkt, så den visas här för enkelhetens skull.
Underliggande intervall: Vyer har olika iteratorkrav för den typ av underliggande intervall som de kan använda. Mer information om vilka typer av iteratorer som finns i iteratorhierarkin för intervall .
Visa iteratorkategori: Iteratorkategorin för vyn. När en vy anpassar ett intervall är iteratortypen för vyn vanligtvis samma som iteratortypen för det underliggande intervallet. Det kan dock vara annorlunda för vissa vyer. Till
reverse_viewexempel har ettbidirectional_iterator, även om det underliggande intervallet har ettrandom_access_iterator.Elementtyp: Typen av element som vyns iterator returnerar.
Storlek: Om vyn kan returnera antalet element som den refererar till. Det går inte att visa alla vyer.
Gemensamt intervall: Anger om vyn är en
common_range, vilket innebär att start-iteratorn och sentinel-typerna är desamma. Vanliga intervall är användbara för kod för förintervall som fungerar med iteratorpar. Ett exempel är iteratorparkonstruktorer för en sekvenscontainer, till exempelvector(ranges::begin(x), ranges::end(x)).Lånat intervall: Anger om vyn är ett lånat intervall.
borrowed_range<T>innebär att du kan använda iteratorer förTefterTförstörs.Ingen standardcontainer är ett lånat intervall eftersom om du förstör containern frigörs elementen och eventuella iteratorer ogiltigförklaras. I så fall säger vi att iteratorerna lämnas "dinglande" efter förstörelsen.
Till exempel
std::ranges::find()returnerar vanligtvis en iterator till det hittade elementet i intervallargumentet. Om intervallargumentet är en tillfällig container (rvalue) är det ett misstag att lagra den returnerade iteratorn och använda den senare eftersom den är "dinglande".Intervallalgoritmer som returnerar iteratorer (eller underordningar) gör det bara när deras argument är lvalues (icke-temporaries) eller lånade intervall. Annars returnerar de ett
std::danglingobjekt som ger en ledtråd i felmeddelanden om vad som gick fel om du försökte använda det som en iterator.Går
constatt iterera: Anger om du kan iterera över enconstinstans av vyn.constAlla vyer kan inte itereras. Om en vy inteconstgår att iterera kan du inte iterera medfor (const auto& element : as_const(theView))eller skicka den till en funktion som tar enconstreferens till vyn och sedan försöker iterera över den.
Iteratorhierarki för intervall
I avsnittet Egenskaper för varje vyklassavsnitt refererar iteratorkategorin i Kategorin Underliggande intervall och Visa iterator till den typ av iterator som området/vyn stöder. Det finns sex kategorier av Ranges-iteratorer som identifieras av C++20-begrepp. Hierarkin för intervall iteratorer, i ökande ordning av kapacitet, är:
| Range iterator-koncept | Beskrivning |
|---|---|
output_range |
Skrivskyddad, går bara framåt; enkelpassning. |
input_range |
Skrivskyddad, går bara framåt; enkelpassning. |
forward_range |
Rör sig bara framåt; multi-pass. |
bidirectional_range |
Kan gå framåt och bakåt; multi-pass. |
random_access_range |
Kan komma åt samlingen med ett index. multi-pass. |
contiguous_range |
Kan komma åt samlingen med ett index och element lagras sammanhängande i minnet. |
Generellt sett har en iterator funktionen hos de iteratorer som föregår den i tabellen. Till exempel bidirectional_range har funktionerna forward_rangei , men inte tvärtom. Förutom input_range, som inte har funktionen output_range eftersom du inte kan skriva till en input_range.
Instruktionen "kräver input_range eller högre" innebär att vyn kan användas med iteratorn input_range, , forward_rangebidirectional_range, random_access_rangeeller contiguous_range eftersom alla är lika kapabla som input_range.
Iteratorhierarkin för intervall är direkt relaterad till iteratorhierarkin. Mer information finns i Iterator-begrepp.