boost iterator adaptor



  • Hallo allerseits,

    hat jmd. von euch Erfahrungen mit o.g. Bibliothek? Ich habe zwar die Docu gelesen aber Bsp. sind da rar.

    Meine Fragen: Kann die Bibl. beliebige Iteratoren wrappen UND das Verhalten des gewrappten annehmen/verändern?

    Z.B.

    // my_iter<std::vector<int>::iterator> soll ein
    // Objekt aus boost::iterator_adaptor sein
    
    std::vector<int> v;
    
    for (my_iter<std::vector<int>::iterator> i=v.begin; i!=v.end(); ++i)
    {
        std::cout << *i << ' '; // nur Primzahlen werden ausgegeben
    }
    


  • Hallo goran,

    goran schrieb:

    Meine Fragen: Kann die Bibl. beliebige Iteratoren wrappen UND das Verhalten des gewrappten annehmen/verändern?

    ja - das ist möglich.
    Für Dein Beispiel unten - nur Elemente mit einer spezifischen Eigenschaft auszugeben - gibt es den filter_iterator, was ein spezialisierter Adapter ist.

    Geht z.B. so:

    #include <boost/iterator/filter_iterator.hpp>
    #include <iostream>
    #include <vector>
    #include <cmath>
    
    bool is_prime( int x )
    {
        if( x < 2 )
            return false;   // no prime is < 2
        int maxi = int(std::sqrt( double( x ) ));
        for( int teiler = 2; teiler <= maxi; ++teiler )
            if( (x % teiler) == 0 )
                return false;
        return true;
    }
    
    int main()
    {
        using namespace std;
        vector< int > v = { 12, 13, 1, 11, 111 };
        auto from = boost::make_filter_iterator( is_prime, begin( v ), end( v ) );
        auto to = boost::make_filter_iterator( is_prime, end( v ), end( v ) );
        for( auto i = from; i != to; ++i )
            cout << *i << ' '; // nur Primzahlen werden ausgegeben
        cout << endl;
        return 0;
    }
    

    ein weiteres Beispiel mit einem Iterator-Adaptor findest Du hier im Forum.

    Gruß
    Werner



  • Danke Werner für die profunde Antwort.

    Ich habe mit deinen Hinweisen versucht mein Problem zu lösen aber es ist leider etwas komplizierter. Ich übergebe einem Parser ein std::multiset<boost::iterator_range<std::string::iterator> > (leider nicht zu ändern) und bekomme diesen befüllt zurück.

    #include <string>
    #include <set>
    #include <iostream>
    #include <boost/range.hpp>
    
    int main()
    {
        std::string s0="einen",s1="schoenen",s2="tag";
    
        boost::iterator_range<std::string::iterator>
            ir0 = boost::make_iterator_range(s0)
          , ir1 = boost::make_iterator_range(s1)
          , ir2 = boost::make_iterator_range(s2)
        ;
    
        std::multiset<boost::iterator_range<std::string::iterator> > irs={ir0,ir1,ir2};
    
        for (auto i: irs) {              // einen    <-> 3 tag
            std::cout << i << std::endl; // schoenen <-> 5 einen
        }                                // tag      <-> 8 schoenen
    }
    

    Nun würde ich gerne das die Reihenfolge im std::multiset eine andere wäre. Quasi den operator< ändern. Für dieses Bsp. würde die Länge des Strings ausreichen. Es gibt da sicher bessere Wege der Länge nach zu sortieren aber es ist auch nur ein Bsp.

    Hat jmd. einen Tip?
    Danke



  • Hallo goran,

    goran schrieb:

    Nun würde ich gerne das die Reihenfolge im std::multiset eine andere wäre. Quasi den operator< ändern. Für dieses Bsp. würde die Länge des Strings ausreichen. Es gibt da sicher bessere Wege der Länge nach zu sortieren aber es ist auch nur ein Bsp.

    Das ist nicht der Job eines Iterator-Adaptors!
    Ein Iterator-Adaptor kann einzelne Elemete ändern oder auch weglassen (Filter-iterator), aber der Charakter der Sequenz bleibt erhalten.

    Du kannst aber einen Funktor-Typ 'Compare' in dem Multiset angeben, der Dir den <-Operator definiert.

    std::multiset< boost::iterator_range<std::string::iterator>, Compare >
    

    Falls Du's nicht allein schaffst, so frage noch mal nach - ich melde mich dann heute abend noch mal.

    Gruß
    Werner


Anmelden zum Antworten