namespace cpp {}

C++ lernen, kennen, anwenden

Benutzer-Werkzeuge

Webseiten-Werkzeuge


kennen:include:ranges

Unterschiede

Hier werden die Unterschiede zwischen zwei Versionen angezeigt.


Nächste Überarbeitung
kennen:include:ranges [2020-07-08 18:10] – angelegt - Externe Bearbeitung 127.0.0.1
Zeile 1: Zeile 1:
 +====== <ranges> ======
 +Bereiche (ab [[..:begriffe#C++20]]) sind Elementfolgen, auf die ''%%begin(r)%%'' und ''%%end(r)%%'' anwendbar sind.
 +Im Namensraum ''std::ranges::views'' oder kurz ''std::views'' 
 +definierte Sichten auf Bereiche lassen sich über Pipes ''|'' aneinander koppeln. 
 +Sie liefern die Werte eines Bereiches einzeln auf Anforderung.
  
 +<code cpp views_pipelines.cpp>
 +#include <iostream>
 +#include <ranges>
 +
 +int main()
 +{
 +    using namespace std::views;
 +    
 +    auto output = 
 +          iota(1)
 +        | filter([](int x){ return x%2 == 0; })
 +        | transform([](int x){ return 3*x; })
 +        | take(10);
 +
 +    // no calculation is done up to here (lazy evaluation)
 +
 +    for (auto e : output) std::cout << e << ' ';
 +}
 +</code>
 +
 +Anfang und Ende eines Views müssen nicht denselben Typ besitzen. Werden Iteratoren des selben Typs benötigt, können diese mit ''std::views::common'' erzeugt werden:
 +
 +<code cpp views_common.cpp>
 +#include <iostream>
 +#include <ranges>
 +#include <vector>
 +
 +int main()
 +{
 +    using namespace std::views;
 +    
 +    auto numbers = iota(1, 10) | common;
 +    auto v = std::vector<int>{numbers.begin(), numbers.end()};
 +    
 +    for (auto e : v) std::cout << e << ' ';
 +}
 +</code>
 +
 +===== Fabriken =====
 +erzeugen Bereiche.
 +
 +| ''empty'' | leerer Bereich |
 +| ''single(value)''| Bereich mit nur einem Wert | 
 +| ''iota(start)''| (unendlicher) Bereich mit Werten beginnend bei ''start'', zählt mit ''++'' hoch | 
 +| ''iota(start, end)''| Zählbereich mit Werten, endet vor ''end''
 +| ''ranges::istream_view<T>(istream)'' | liest Werte vom Typ ''T'' aus dem Eingabestrom ''istream'' |
 +
 +<code cpp istream_view.cpp>
 +#include <iostream>
 +#include <ranges>
 +#include <string>
 +#include <sstream>
 +
 +int main()
 +{
 +  auto input = std::istringstream{"0 1 2 3 4 5 6 7 8 9"};
 +  auto below_5 = std::ranges::istream_view<int>(input) 
 +    | std::views::take_while([](auto x) { return x < 5; });
 +
 +  for (auto e : below_5) std::cout << e << ' ';
 +}
 +</code>
 +
 +===== Sichten =====
 +übernehmen einen Bereich, verarbeiten dessen Elemente ''e'' und geben sie weiter.
 +
 +| ''all'' | gibt alle Elemente weiter |
 +| ''common'' | erzeugt Bereich, bei dem ''%%begin(r)%%'' und ''%%end(r)%%'' den selben Typ haben |
 +| ''counted(iter, n)'' | liefert ''n'' Werte, beginnend mit Iterator ''iter'' |
 +| ''drop(n)'' | überspringt die ersten ''n'' Elemente |
 +| ''drop_while(pred)'' | überspringt Elemente, solange ''pred(e)'' erfüllt ist |
 +| ''filter(pred)'' | gibt nur die Elemente weiter, für die ''pred(e)'' erfüllt ist |
 +| ''reverse'' | kehrt Reihenfolge der Elemente um |
 +| ''take(n)'' | gibt nur die ersten ''n'' Elemente weiter |
 +| ''take_while(pred)'' | gibt Elemente nur solange weiter, wie ''pred(e)'' erfüllt ist |
 +| ''transform(f)'' | wendet ''f'' auf jedes Element ''e'' an, gibt ''f(e)'' weiter  |
 +| | |
 +| ''join'' | wandelt einen Bereich von Bereichen in einen "flachen" Bereich um |
 +| ''split(delim)'' | erzeugt einen Bereich von Teilbereichen, ''delim'' kann einzelnes Element oder eine Folge sein  |
 +| | |
 +| ''elements<N>'' | gibt den ''N''-ten Bestandteil von tupelartigen Elementen weiter |
 +| ''keys'' | gibt alle Schlüssel von Schlüssel-Wert-Paaren weiter (''elements<0>'') |
 +| ''values'' | gibt alle Werte von Schlüssel-Wert-Paaren weiter (''elements<1>'') |
 +
 +
 +===== Beispiele =====
 +
 +<code cpp views_examples.cpp>
 +#include <ranges>
 +#include <iostream>
 +#include <map>
 +#include <string>
 +#include <vector>
 +
 +template <typename Range, typename Msg>
 +void show(Range&& r, Msg message)
 +{
 +    std::cout.width(30);
 +    std::cout << std::left << message <<  " : [";
 +    int cnt = 0;    
 +    for (auto&& e : r) 
 +    {
 +        std::cout << (cnt++ ? ",":"");
 +        std::cout << e;    
 +    }    
 +    std::cout << "]\n";
 +}
 +
 +template <typename Range, typename Msg>
 +void show_range_of_ranges(Range&& r, Msg message)
 +{
 +    std::cout.width(30);
 +    std::cout << std::left << message << " : [";
 +    int cnt = 0;    
 +    for (auto&& inner_range : r) 
 +    {
 +        std::cout << (cnt++ ? ",":"") << "[";
 +        int inner_cnt = 0;    
 +        for (auto&& e : inner_range) 
 +        {
 +            std::cout << (inner_cnt++ ? ",":"");
 +            std::cout << e;    
 +        }
 +        std::cout << "]";        
 +    }    
 +    std::cout << "]\n";
 +}
 +
 +int main()
 +{
 +    using namespace std::views;
 +    
 +    auto v = std::vector{0,1,2,3,4,5};
 +    auto s = std::string{"AB CD E"};
 +    auto m = std::map<std::string,int>{{"wrong", 6*9}, {"answer", 42}};
 +    
 +    show( empty<int>, "empty<T>");
 +    show( single(42), "single(42)");
 +    show( iota(0,6), "iota(0,6)");
 +    show( iota(0) | take(3), "iota(0) | take(3)");
 +    show( counted(begin(v), 3), "counted(begin(v),3)");
 +    show( v | all, "v | all");
 +    show( v | reverse, "v | reverse");
 +    show( v | take_while([](int x){ return x < 3; }), "v | take_while(below_3)");
 +    show( v | drop_while([](int x){ return x < 3; }), "v | drop_while(below_3)");
 +    show( v | filter([](int x){ return x%2 != 0; }), "v | filter(odd)");
 +    show( v | transform([](int x){ return x*x; }), "v | transform(square)");
 +    
 +    show( s , "s");
 +    show_range_of_ranges( s | split(' '), "s | split(\' \')");
 +    show( s | split(' ') | join, "s | split(\' \') | join");
 +    
 +    show( m | keys , "m | keys");
 +    show( m | values , "m | values");
 +}
 +</code>
 +erzeugt die Ausgabe
 +<file>
 +empty<T>                       : []
 +single(42)                     : [42]
 +iota(0,6)                      : [0,1,2,3,4,5]
 +iota(0) | take(3)              : [0,1,2]
 +counted(begin(v),3)            : [0,1,2]
 +v | all                        : [0,1,2,3,4,5]
 +v | reverse                    : [5,4,3,2,1,0]
 +v | take_while(below_3)        : [0,1,2]
 +v | drop_while(below_3)        : [3,4,5]
 +v | filter(odd)                : [1,3,5]
 +v | transform(square)          : [0,1,4,9,16,25]
 +s                              : [A,B, ,C,D, ,E]
 +s | split(' '                : [[A,B],[C,D],[E]]
 +s | split(' ') | join          : [A,B,C,D,E]
 +m | keys                       : [answer,wrong]
 +m | values                     : [42,54]
 +</file>
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