namespace cpp

C++ lernen, kennen, anwenden

Benutzer-Werkzeuge

Webseiten-Werkzeuge


kennen:include:ranges

Dies ist eine alte Version des Dokuments!


<ranges>

Views lassen sich über Pipes | aneinander koppeln und liefern die Werte eines Bereiches einzeln auf Anforderung.

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 << ' ';
}

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:

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 << ' ';
}

Beispiel

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");
}

erzeugt die Ausgabe

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]
kennen/include/ranges.1591027403.txt.gz · Zuletzt geändert: 2020-06-01 18:03 von rrichter