for_each() - Schleifeninterval



  • Der for_each() Algorithmus ist ja eigentlich nur sowas wie eine for-Schleife mit Interval "i=i+1", also wird immer um ein Element hochgezählt!?
    Kann ich das Interval auch irgendwie verändern, z.B. dass um 3 hochgezählt wird. (i=i+3)
    Oder is das um eins hochzählen bei for_each einfach standard?

    MfG
    Stromberg



  • for_each aus <algorithm> ist dazu da, um eine übergebene Funktion mit jedem Element einmal aufzurufen.

    Da wäre ein anderer Intervall relativ sinnlos, oder?

    Wenn du was anderes brauchst, kannst du - wie du schon sagtest - einfach eine eigene for-Schleife nutzen.


  • Mod

    Im allgemeinen Fall würde man wohl stride-Iteratoren einführen, um die zu bearbeitende Sequenz zu adaptieren. Gelegentlich könnte aber auch ein entsprechend erweiterter Algorithmus sinnvoll sein:

    template<typename InputIterator, typename Function>
    Function for_each_by_stride(InputIterator first, InputIterator last, Function f, typename std::iterator_traits< InputIterator >::difference_type stride = 1)
    {
        static const struct
        {
            bool operator()(InputIterator& it, const InputIterator& last, typename std::iterator_traits< InputIterator >::difference_type dist, input_iterator_tag) const
            {
                while ( dist-- != 0 )
                    if ( it != last )
                        ++it;
                    else
                        return false;
                return it != last;
            }
            bool operator()(InputIterator& it, const InputIterator& last, typename std::iterator_traits< InputIterator >::difference_type dist, random_access_iterator_tag) const
            {
                if ( distance( it, last ) <= dist )
                    return false;
                it += dist;
                return true;
            }
        } advance_to;
    
        if ( first != last )
            do
                f( *first );
            while ( advance_to( first, last, stride, typename std::iterator_traits< InputIterator >::iterator_category() ) );
        return f;
    }
    

    Kompliziert wird das Ganze deshalb, weil ich nicht voraussetzen möchte, dass distance(last,first) ein Vielfaches von stride sein muss. Eine andere Möglichkeit wäre ein angepasstes Funktions-Objekt, dass nur bei jedem x-ten Aufruf tatsächlich etwas durchführt.



  • for_each heißt "für jeden". Wenns nur jeder dritte wäre, wäre es nicht "für jeden". Also ist es richtig, das for_each nicht jeden dritten aufruft. Ein wenig Formalismus sollte man schon beachten. 😉


Anmelden zum Antworten