namespace cpp {}

C++ lernen, kennen, anwenden

Benutzer-Werkzeuge

Webseiten-Werkzeuge


kennen:include:ranges

Unterschiede

Hier werden die Unterschiede zwischen zwei Versionen angezeigt.

Link zu dieser Vergleichsansicht

Beide Seiten der vorigen RevisionVorhergehende Überarbeitung
Nächste Überarbeitung
Vorhergehende Überarbeitung
Nächste ÜberarbeitungBeide Seiten der Revision
kennen:include:ranges [2024-02-11 17:30] – [Sichten] rrichterkennen:include:ranges [2024-02-20 15:25] rrichter
Zeile 1: Zeile 1:
 ====== <ranges> ====== ====== <ranges> ======
-Bereiche (ab [[..:begriffe#C++20]]) sind Elementfolgen, auf die ''%%begin(r)%%'' und ''%%end(r)%%'' anwendbar sind.+Bereiche sind Elementfolgen, auf die ''%%begin(r)%%'' und ''%%end(r)%%'' anwendbar sind. 
 +Die Algorithmen der Standardbibliothek erlauben seit [[..:begriffe#C++20]] die Schreibweise ''std::ranges::sort(v)'' statt ''std::sort(begin(v), end(v))''
 +Allerdings sind die einzelnen Algorithmen jeweils nacheinander auszuführen, also nicht koppelbar. 
 +MIt einem anderen Ansatz soll dieser Nachteil behoben werden. 
 Im Namensraum ''std::ranges::views'' oder kurz ''std::views''  Im Namensraum ''std::ranges::views'' oder kurz ''std::views'' 
 definierte Sichten auf Bereiche lassen sich über Pipes ''|'' aneinander koppeln.  definierte Sichten auf Bereiche lassen sich über Pipes ''|'' aneinander koppeln. 
-Sie liefern die Werte eines Bereiches einzeln auf Anforderung.+Sie liefern die Werte eines Bereiches einzeln auf Anforderung, also über [[https://de.wikipedia.org/wiki/Lazy_Evaluation|lazy evaluation]].
  
 <code cpp views_pipelines.cpp> <code cpp views_pipelines.cpp>
Zeile 40: Zeile 44:
          
     for (auto e : v) std::cout << e << ' ';     for (auto e : v) std::cout << e << ' ';
 +}
 +</code>
 +===== Quellen und Senken =====
 +Sequentielle und assoziative (!) Container können als Quellbereiche dienen. Mit ''ranges::to<Container>()'' (C++23) wird ein neuer Container als Senke für die verarbeiteten Daten erzeugt. Der Elementtyp wird automatisch bestimmt.
 +
 +<code cpp to.cpp>
 +#include <iostream>
 +#include <ranges>
 +#include <set>
 +#include <vector>
 +
 +int main()
 +{
 +    std::set s{ 'h', 'a', 'l', 'o' };
 +    auto v = s | std::views::take(2) | std::ranges::to<std::vector>();
 +    for (auto e : v) std::cout << e; 
 } }
 </code> </code>
  
 ===== Fabriken ===== ===== Fabriken =====
-erzeugen Bereiche.+erzeugen Bereiche (° : definiert in [[..:begriffe#C++20]], ³ : [[..:begriffe#C++23]]): 
  
-| ''empty'' | leerer Bereich | +| ''empty'' | leerer Bereich | ° 
-| ''single(value)''| Bereich mit nur einem Wert |  +| ''single(value)''| Bereich mit nur einem Wert | ° |  
-| ''iota(start)''| (unendlicher) Bereich mit Werten beginnend bei ''start'', zählt mit ''++'' hoch |  +| ''iota(start)''| (unendlicher) Bereich mit Werten beginnend bei ''start'', zählt mit ''++'' hoch | ° |  
-| ''iota(start, end)''| Zählbereich mit Werten, endet vor ''end'' |  +| ''iota(start, end)''| Zählbereich endet vor ''end'' | ° |  
-| ''ranges::istream_view<T>(istream)'' | liest Werte vom Typ ''T'' aus dem Eingabestrom ''istream'' |+| ''ranges::istream_view<T>(istream)'' | liest Werte vom Typ ''T'' aus dem Eingabestrom ''istream'' | ° | 
 +| ''repeat(value)'' | wiederholt den Wert unbegrenzt oft | ³ | 
 +| ''repeat(value, n)'' | liefert den Wert genau ''n'' Mal | ³ |
  
 <code cpp istream_view.cpp> <code cpp istream_view.cpp>
 #include <iostream> #include <iostream>
 #include <ranges> #include <ranges>
-#include <string> 
 #include <sstream> #include <sstream>
 +#include <string>
  
 int main() int main()
 { {
-  auto input = std::istringstream{"0 1 2 3 4 5 6 7 8 9"}; +    auto input = std::istringstream{"0 1 2 3 4 5 6 7 8 9"}; 
-  auto below_5 = std::ranges::istream_view<int>(input)  +    auto below_5 = std::ranges::istream_view<int>(input)  
-    | std::views::take_while([](auto x) { return x < 5; }); +        | std::views::take_while([](auto x) { return x < 5; });
  
-  for (auto e : below_5) std::cout << e << ' ';+    for (auto e : below_5) std::cout << e << ' ';
 } }
 </code> </code>
  
 ===== Sichten ===== ===== Sichten =====
-übernehmen einen Bereich, verarbeiten dessen Elemente ''e'' und geben sie weiter.+übernehmen einen oder mehrere Bereiche, verarbeiten dessen / deren Elemente ''e'' und geben sie weiter.
  
-^ ^ ^ seit* ^ 
 | ''all'' | gibt alle Elemente weiter | ° | | ''all'' | gibt alle Elemente weiter | ° |
-| ''adjacent<N>'' | erzeugt Tuple aus N benachbarten Elementen  | ³ | +| ''adjacent<N>'' | erzeugt Tupel aus ''N'' benachbarten Elementen  | ³ | 
-| ''adjacent[_transform(f)'' | wendet ''f'' auf die erzeugten Tupel an | ³ |+| ''adjacent_transform<N>(f)'' | wendet ''f(e1,e2,...)'' auf ''N'' benachbarte Elemente ''e1,e2,...'' an | ³ |
 | ''as_const'' | Elemente dürfen nicht verändert werden | ³ | | ''as_const'' | Elemente dürfen nicht verändert werden | ³ |
 | ''as_rvalue'' | erspart Kopieren: Elemente können per "move" übernommen werden | ³ | | ''as_rvalue'' | erspart Kopieren: Elemente können per "move" übernommen werden | ³ |
 | ''common'' | erzeugt Bereich, bei dem ''%%begin(r)%%'' und ''%%end(r)%%'' den selben Typ haben | ° | | ''common'' | erzeugt Bereich, bei dem ''%%begin(r)%%'' und ''%%end(r)%%'' den selben Typ haben | ° |
-| ''cartesian_product(rg1,rg2,...)'' | bildet Tupel aus jedem mit jedem aus 2 oder mehr gegebenen Bereichen | ³ |+| ''cartesian_product(rg1,rg2,...)'' | bildet die Kreuzmenge, d.h. alle Tupel aus jedem mit jedem aus 2 oder mehr gegebenen Bereichen | ³ |
 | ''chunk(n)'' | unterteilt in Teilbereiche aus ''n'' aufeinander folgenden Elementen | ³ | | ''chunk(n)'' | unterteilt in Teilbereiche aus ''n'' aufeinander folgenden Elementen | ³ |
 | ''chunk_by(pred)'' | aufeinander folgende Elemente ''a'',''b'' gehören zum gleichen Teilbereich, wenn ''pred(a,b)'' wahr ist | ³ | | ''chunk_by(pred)'' | aufeinander folgende Elemente ''a'',''b'' gehören zum gleichen Teilbereich, wenn ''pred(a,b)'' wahr ist | ³ |
Zeile 91: Zeile 112:
 | ''keys'' | gibt alle Schlüssel von Schlüssel-Wert-Paaren weiter (''elements<0>'') | ° | | ''keys'' | gibt alle Schlüssel von Schlüssel-Wert-Paaren weiter (''elements<0>'') | ° |
 | ''pairwise'' | ''adjacent<2>'' | ³ | | ''pairwise'' | ''adjacent<2>'' | ³ |
-| ''pairwise_transform(f)'' | ''adjacent_tansform(f)'' | ³ | +| ''pairwise_transform(f)'' | ''adjacent_transform<2>(f)'' | ³ |
-| ''repeat(x,n)'' | wiederholt x n Mal oder immer wieder, falls n fehlt | ³ |+
 | ''reverse'' | kehrt Reihenfolge der Elemente um | ° | | ''reverse'' | kehrt Reihenfolge der Elemente um | ° |
-| ''slide(n)'' | erzeugt ein gleitendes Fenster aus n Elementen | ³ |+| ''slide(n)'' | erzeugt einen gleitenden Fensterbereich aus n Elementen | ³ |
 | ''stride(n)'' | springt immer n Elemente weiter | ³ | | ''stride(n)'' | springt immer n Elemente weiter | ³ |
 | ''take(n)'' | gibt nur die ersten ''n'' Elemente weiter | ° | | ''take(n)'' | gibt nur die ersten ''n'' Elemente weiter | ° |
Zeile 102: Zeile 122:
 | ''values'' | gibt alle Werte von Schlüssel-Wert-Paaren weiter (''elements<1>'') | ° | | ''values'' | gibt alle Werte von Schlüssel-Wert-Paaren weiter (''elements<1>'') | ° |
 | ''zip(rg1,rg2,...)'' | erzeugt Tupel aus zwei oder mehr Bereichen | ³ | | ''zip(rg1,rg2,...)'' | erzeugt Tupel aus zwei oder mehr Bereichen | ³ |
-| ''zip_transform(f)''wendet ''f'' auf die erzeugten Tupel an | ³ |+| ''zip_transform(f,rg1,rg2,...)''ruft ''f(e1,e2,...)'' mit Argumenten ''e1,e2,...'' aus gegebenen Bereichen auf | ³ |
  
-° : seit C++20, ³ : seit C++23 
  
 ===== Beispiele ===== ===== Beispiele =====
Zeile 114: Zeile 133:
 #include <string> #include <string>
 #include <vector> #include <vector>
 +
 +// waiting for P2286 Formatting Ranges ...
  
 template <typename Range, typename Msg> template <typename Range, typename Msg>
kennen/include/ranges.txt · Zuletzt geändert: 2024-02-22 21:04 von rrichter

Donate Powered by PHP Valid HTML5 Valid CSS Driven by DokuWiki