it-swarm.com.de

Vorteile von std :: for_each gegenüber der Schleife

Gibt es irgendwelche Vorteile von std::for_each gegenüber for-Schleife? Für mich scheint std::for_each nur die Lesbarkeit von Code zu behindern. Warum empfehlen dann einige Kodierungsstandards die Verwendung? 

147
missingfaktor

Die schöne Sache mit C++ 11 (zuvor C++ 0x genannt) ist, dass diese langweilige Debatte beigelegt wird.

Ich meine, niemand, der bei klarem Verstand, der eine ganze Sammlung durchlaufen möchte, wird dies immer noch verwenden

for(auto it = collection.begin(); it != collection.end() ; ++it)
{
   foo(*it);
}

Oder dieses

for_each(collection.begin(), collection.end(), [](Element& e)
{
   foo(e);
});

wenn die bereichsbasierte for loop -Syntax verfügbar ist:

for(Element& e : collection)
{
   foo(e);
}

Diese Art von Syntax ist seit einiger Zeit in Java und C # verfügbar, und tatsächlich gibt es in jedem neuen Java- oder C # -Code, den ich sah, weit mehr foreach-Schleifen als klassische for-Schleifen.

160
Thomas Petit

Hier sind einige Gründe:

  1. Es scheint die Lesbarkeit zu behindern, nur weil Sie nicht daran gewöhnt sind und/oder nicht die richtigen Werkzeuge verwenden, um es wirklich einfach zu machen. (Siehe boost :: range und boost :: bind/boost :: lambda für Helfer. Viele davon werden in C++ 0x verwendet und machen for_each und verwandte Funktionen nützlicher.)

  2. Sie können auf for_each einen Algorithmus schreiben, der mit jedem Iterator funktioniert. 

  3. Es verringert die Wahrscheinlichkeit dummer Tippfehler.

  4. Es öffnet Ihnen auch den Rest der STL-Algorithmen wie find_if, sort, replace usw. und diese werden nicht mehr so ​​seltsam aussehen. Dies kann ein großer Gewinn sein.

Update 1:

Am wichtigsten ist, dass es Ihnen hilft, über for_each vs. for-loops hinauszugehen, so wie das alles ist, und sich die anderen STL-Alogs anzusehen, wie find/sort/partition/copy_replace_if, Parallell-Ausführung ... oder was auch immer.

Eine Menge der Verarbeitung kann mit "dem Rest" der Geschwister von for_each sehr knapp geschrieben werden. Wenn Sie jedoch lediglich eine for-Schleife mit verschiedenen internen Logikschreibweisen schreiben, werden Sie nie erfahren, wie Sie diese verwenden am Ende das Rad immer wieder neu erfinden. 

Und (der bald verfügbare Range-Style für_each):

for_each(monsters, boost::mem_fn(&Monster::think));

Oder mit C++ x11-Lambdas:

for_each(monsters, [](Monster& m) { m.think(); });

ist IMO besser lesbar als:

for(Monsters::iterator i = monsters.begin(); i != monsters.end(); ++i) {
    i->think();
} 

Auch dies (oder mit Lambdas, siehe andere):

for_each(bananas, boost::bind(&Monkey::eat, my_monkey, _1));

Ist prägnanter als:

for(Bananas::iterator i = bananas.begin(); i != bananas.end(); ++i) {
    my_monkey->eat(*i);
} 

Vor allem, wenn Sie mehrere Funktionen nacheinander aufrufen müssen ... aber das ist vielleicht nur ich. ;)

Update 2 : Ich habe meine eigenen One-Liner-Wrapper von STL-Algos geschrieben, die mit Bereichen anstatt mit Iteratorenpaaren arbeiten. boost :: range_ex, einmal veröffentlicht, wird das enthalten und vielleicht wird es auch in C++ 0x vorhanden sein?

46
Macke

for_each ist generischer. Sie können es verwenden, um über jeden Typ von Container zu iterieren (indem Sie die Start-/End-Iteratoren übergeben). Unter einer Funktion, die for_each verwendet, können Sie möglicherweise Container auslagern, ohne den Iterationscode aktualisieren zu müssen. Sie müssen berücksichtigen, dass es auf der Welt andere Container als std :: vector und einfache alte C-Arrays gibt, um die Vorteile von for_each zu erkennen.

Der Hauptnachteil von for_each besteht darin, dass es einen Funktor erfordert, sodass die Syntax umständlich ist. Dies ist in C++ 0x mit der Einführung von Lambdas behoben:

std::vector<int> container;
...
std::for_each(container.begin(), container.end(), [](int& i){
    i+= 10;
});

Das wird Ihnen in 3 Jahren nicht komisch vorkommen.

22
Terry Mahaffey

Wenn ich std::for_each (schreibe Spezialfunktionalitäten/komplizierte boost::lambdas) verwenden möchte, brauche ich jedes Mal, wenn ich aus dem Weg gehe, BOOST_FOREACH und C++ 0xs Range-based zum besseren Verständnis:

BOOST_FOREACH(Monster* m, monsters) {
     if (m->has_plan()) 
         m->act();
}

vs

std::for_each(monsters.begin(), monsters.end(), 
  if_then(bind(&Monster::has_plan, _1), 
    bind(&Monster::act, _1)));
17
UncleBens

es ist sehr subjektiv, einige werden sagen, dass die Verwendung von for_each den Code more lesbar macht, da verschiedene Sammlungen mit denselben Konventionen behandelt werden können. for_each itslef ist als Schleife implementiert

template<class InputIterator, class Function>
  Function for_each(InputIterator first, InputIterator last, Function f)
  {
    for ( ; first!=last; ++first ) f(*first);
    return f;
  }

es liegt also an Ihnen, zu wählen, was für Sie richtig ist. 

11
Alon

Sie haben größtenteils recht: Meistens ist std::for_each ein Nettoverlust. Ich würde so weit gehen, for_each mit goto zu vergleichen. goto bietet die vielseitigste Flusssteuerung - Sie können damit praktisch jede andere Steuerungsstruktur implementieren, die Sie sich vorstellen können. Diese Vielseitigkeit bedeutet jedoch, dass ein goto für sich genommen praktisch nichts darüber aussagt, was in dieser Situation beabsichtigt ist. Infolgedessen verwendet fast niemand, der bei Verstand ist, goto, außer als letztes Mittel.

Unter den Standardalgorithmen ist for_each ähnlich - es kann praktisch alles implementiert werden, was bedeutet, dass Sie mit for_each praktisch nichts darüber erfahren, wofür es in dieser Situation verwendet wird. Unglücklicherweise handelt die Einstellung der Menschen zu for_each davon, wo sich ihre Einstellung zu goto etwa 1970 befand - ein paar Leute hatten begriffen, dass es so sein sollte wird nur als letzter Ausweg verwendet, aber viele betrachten ihn immer noch als den primären Algorithmus und verwenden selten, wenn überhaupt, einen anderen. Die überwiegende Mehrheit der Zeit zeigte sogar ein kurzer Blick, dass eine der Alternativen drastisch überlegen war.

Ich bin mir zum Beispiel ziemlich sicher, dass ich den Überblick darüber verloren habe, wie oft Leute Code geschrieben haben, um den Inhalt einer Sammlung mit for_each auszudrucken. Aufgrund der Beiträge, die ich gesehen habe, ist dies möglicherweise die häufigste Verwendung von for_each. Sie enden mit etwas wie:

class XXX { 
// ...
public:
     std::ostream &print(std::ostream &os) { return os << "my data\n"; }
};

Und ihr Beitrag fragt, welche Kombination von bind1st, mem_fun usw. sie benötigen, um etwas zu machen wie:

std::vector<XXX> coll;

std::for_each(coll.begin(), coll.end(), XXX::print);

arbeite und drucke die Elemente von coll aus. Wenn es wirklich genau so funktioniert hat, wie ich es dort geschrieben habe, wäre es mittelmäßig, aber nicht - und wenn Sie es zum Laufen gebracht haben, ist es schwierig, die wenigen Codeteile zu finden, die mit dem zu tun haben, was ist geht weiter zwischen den Stücken, die es zusammenhalten.

Zum Glück gibt es einen viel besseren Weg. Fügen Sie eine normale Stream Inserter-Überladung für XXX hinzu:

std::ostream &operator<<(std::ostream *os, XXX const &x) { 
   return x.print(os);
}

und benutze std::copy:

std::copy(coll.begin(), coll.end(), std::ostream_iterator<XXX>(std::cout, "\n"));

Das funktioniert - und es ist praktisch keine Arbeit erforderlich, um herauszufinden, dass der Inhalt von coll auf std::cout gedruckt wird.

10
Jerry Coffin

Wie viele Algorithmusfunktionen besteht die erste Reaktion darin, zu glauben, dass die Verwendung von foreach unleserlicher ist als eine Schleife. Es war ein Thema vieler Flammenkriege.

Wenn Sie sich erst einmal an das Idiom gewöhnt haben, kann es nützlich sein. Ein offensichtlicher Vorteil besteht darin, dass der Codierer den inneren Inhalt der Schleife von der tatsächlichen Iterationsfunktion trennen muss. (OK, ich denke, es ist ein Vorteil. Andere sagen, Sie hacken den Code ohne wirklichen Nutzen ab).

Ein weiterer Vorteil ist, wenn ich foreach sehe, ich kennt dass entweder jedes Element verarbeitet wird oder eine Ausnahme ausgelöst wird.

EIN for loop erlaubt verschiedene Optionen zum Beenden der Schleife. Sie können die Schleife laufen lassen oder die brechen Schlüsselwort, um explizit aus der Schleife zu springen, oder verwenden Sie das rückkehr Schlüsselwort, um die gesamte Funktion in der Schleife zu beenden. Im Gegensatz, für jeden lässt diese Optionen nicht zu, wodurch sie lesbarer wird. Sie können nur einen Blick auf den Funktionsnamen werfen, und Sie kennen die volle Natur der Iteration.

Hier ist ein Beispiel für eine Verwirrung for Schleife:

for(std::vector<widget>::iterator i = v.begin(); i != v.end(); ++i)
{
   /////////////////////////////////////////////////////////////////////
   // Imagine a page of code here by programmers who don't refactor
   ///////////////////////////////////////////////////////////////////////
   if(widget->Cost < calculatedAmountSofar)
   {
        break;
   }
   ////////////////////////////////////////////////////////////////////////
   // And then some more code added by a stressed out juniour developer
   // *#&$*)#$&#(#)$#(*$&#(&*^$#(*$#)($*#(&$^#($*&#)$(#&*$&#*$#*)$(#*
   /////////////////////////////////////////////////////////////////////////
   for(std::vector<widgetPart>::iterator ip = widget.GetParts().begin(); ip != widget.GetParts().end(); ++ip)
   {
      if(ip->IsBroken())
      {
         return false;
      }
   }
}
10
Andrew Shepherd

Der Vorteil des Schreibens von Funktionen für mehr Lesbarkeit wird möglicherweise nicht angezeigt, wenn for(...) und for_each(...).

Wenn Sie alle Algorithmen in funktional.h verwenden, anstatt For-Loops zu verwenden, wird der Code deutlich lesbarer.

iterator longest_tree = std::max_element(forest.begin(), forest.end(), ...);
iterator first_leaf_tree = std::find_if(forest.begin(), forest.end(), ...);
std::transform(forest.begin(), forest.end(), firewood.begin(), ...);
std::for_each(forest.begin(), forest.end(), make_plywood);

ist viel lesbarer als;

Forest::iterator longest_tree = it.begin();
for (Forest::const_iterator it = forest.begin(); it != forest.end(); ++it{
   if (*it > *longest_tree) {
     longest_tree = it;
   }
}

Forest::iterator leaf_tree = it.begin();
for (Forest::const_iterator it = forest.begin(); it != forest.end(); ++it{
   if (it->type() == LEAF_TREE) {
     leaf_tree  = it;
     break;
   }
}

for (Forest::const_iterator it = forest.begin(), jt = firewood.begin(); 
     it != forest.end(); 
     it++, jt++) {
          *jt = boost::transformtowood(*it);
    }

for (Forest::const_iterator it = forest.begin(); it != forest.end(); ++it{
    std::makeplywood(*it);
}

Und das finde ich so schön, generalisiere die for-loops auf einzeilige Funktionen =)

8
Viktor Sehr

Einfach: for_each ist nützlich, wenn Sie bereits über eine Funktion für jedes Array-Element verfügen, so dass Sie kein Lambda schreiben müssen. Sicherlich das

for_each(a.begin(), a.end(), a_item_handler);

ist besser als

for(auto& item: a) {
    a_item_handler(a);
}

Darüber hinaus durchläuft die for-Schleife des Bereichs nur ganze Container von Anfang bis Ende, während for_each flexibler ist.

5
Tigran Saluev

Die for_each-Schleife soll die Iteratoren (Detail, wie eine Schleife implementiert wird) vor dem Benutzercode ausblenden und eine eindeutige Semantik für die Operation definieren: Jedes Element wird genau einmal wiederholt.

Das Problem mit der Lesbarkeit im aktuellen Standard besteht darin, dass anstelle eines Codeblocks als letztes Argument ein Funktor benötigt wird. In vielen Fällen müssen Sie einen bestimmten Funktortyp dafür schreiben. Das wird zu weniger lesbarem Code, da functor-Objekte nicht direkt definiert werden können (in einer Funktion definierte lokale Klassen können nicht als Vorlagenargumente verwendet werden) und die Implementierung der Schleife muss aus der tatsächlichen Schleife verschoben werden.

struct myfunctor {
   void operator()( int arg1 ) { code }
};
void apply( std::vector<int> const & v ) {
   // code
   std::for_each( v.begin(), v.end(), myfunctor() );
   // more code
}

Wenn Sie für jedes Objekt eine bestimmte Operation ausführen möchten, können Sie std::mem_fn oder boost::bind (std::bind im nächsten Standard) oder boost::lambda (Lambdas im nächsten Standard) verwenden, um es einfacher zu machen:

void function( int value );
void apply( std::vector<X> const & v ) {
   // code
   std::for_each( v.begin(), v.end(), boost::bind( function, _1 ) );
   // code
}

Welches ist nicht weniger lesbar und kompakter als die von Hand gerollte Version, wenn Sie über eine Funktion/Methode verfügen, die aufgerufen werden soll. Die Implementierung könnte andere Implementierungen der for_each-Schleife bereitstellen (Parallelverarbeitung denken).

Der aufkommende Standard behebt einige der Mängel auf unterschiedliche Weise, und es werden lokal definierte Klassen als Argumente für Vorlagen zugelassen:

void apply( std::vector<int> const & v ) {
   // code
   struct myfunctor {
      void operator()( int ) { code }
   };
   std::for_each( v.begin(), v.end(), myfunctor() );
   // code
}

Verbesserung der Codelokalität: Wenn Sie browsen, können Sie sehen, was dort gemacht wird. Tatsächlich müssen Sie nicht einmal die Klassensyntax verwenden, um den Functor zu definieren, sondern verwenden Sie direkt dort ein Lambda:

void apply( std::vector<int> const & v ) {
   // code
   std::for_each( v.begin(), v.end(), 
      []( int ) { // code } );
   // code
}

Selbst wenn für for_each ein bestimmtes Konstrukt vorhanden ist, das es natürlicher macht:

void apply( std::vector<int> const & v ) {
   // code
   for ( int i : v ) {
      // code
   }
   // code
}

Ich neige dazu, das for_each-Konstrukt mit von Hand gerollten Schleifen zu mischen. Wenn nur ein Aufruf einer vorhandenen Funktion oder Methode erforderlich ist (for_each( v.begin(), v.end(), boost::bind( &Type::update, _1 ) )), gehe ich für das for_each-Konstrukt, das dem Code eine Menge Boiler-Platten-Iterator-Zeug wegnimmt. Wenn ich etwas komplexeres brauche und keinen Funktionszeiger nur ein paar Zeilen über der tatsächlichen Verwendung implementieren kann, rolle ich meine eigene Schleife (hält die Operation an Ort und Stelle). In nicht kritischen Abschnitten des Codes kann ich BOOST_FOREACH verwenden (ein Mitarbeiter hat mich dazu gebracht)

Ich habe std::for_each nicht gern gesehen und dachte, dass es ohne Lambda völlig falsch gemacht wurde. Allerdings habe ich vor einiger Zeit meine Meinung geändert und jetzt liebe ich es wirklich. Ich denke, es verbessert sogar die Lesbarkeit und macht es einfacher, Ihren Code auf TDD-Art zu testen.

Der std::for_each-Algorithmus kann gelesen werden als etwas mit allen Elementen im Bereich tun, was can die Lesbarkeit verbessert. Angenommen, die Aktion, die Sie ausführen möchten, ist 20 Zeilen lang, und die Funktion, in der die Aktion ausgeführt wird, ist auch ungefähr 20 Zeilen lang. Das würde eine Funktion mit einer herkömmlichen for-Schleife 40 Zeilen lang machen und mit std::for_each nur etwa 20, was wahrscheinlich einfacher zu verstehen ist.

Funktoren für std::for_each sind eher allgemeiner und somit wiederverwendbar, z.

struct DeleteElement
{
    template <typename T>
    void operator()(const T *ptr)
    {
        delete ptr;
    }
};

Und im Code hätten Sie nur einen Einzeiler wie std::for_each(v.begin(), v.end(), DeleteElement()), der IMO etwas besser ist als eine explizite Schleife.

All diese Funktionen sind normalerweise einfacher bei Unit-Tests als eine explizite for-Schleife in der Mitte einer langen Funktion, und das allein ist schon ein großer Gewinn für mich.

std::for_each ist im Allgemeinen auch zuverlässiger, da es unwahrscheinlicher ist, dass Sie mit der Reichweite einen Fehler machen.

Und schließlich kann der Compiler für std::for_each etwas besseren Code erzeugen als für bestimmte Arten von handgefertigten Schleifen, da er (for_each) immer für Compiler gleich aussieht und Compiler-Schreiber ihr gesamtes Wissen zur Verfügung stellen können. um es so gut wie möglich zu machen.

Gleiches gilt für andere Standardalgorithmen wie find_if, transform usw.

3
Dmitry

Abgesehen von Lesbarkeit und Leistung wird die Konsistenz häufig übersehen. Es gibt viele Möglichkeiten, eine for (oder while) -Schleife über Iteratoren zu implementieren, von:

for (C::iterator iter = c.begin(); iter != c.end(); iter++) {
    do_something(*iter);
}

zu:

C::iterator iter = c.begin();
C::iterator end = c.end();
while (iter != end) {
    do_something(*iter);
    ++iter;
}

mit vielen Beispielen dazwischen bei unterschiedlichem Wirkungsgrad und Fehlerpotenzial.

Die Verwendung von for_each erzwingt jedoch Konsistenz durch Abstraktion der Schleife:

for_each(c.begin(), c.end(), do_something);

Das einzige, worüber Sie sich jetzt Sorgen machen müssen, ist: Implementieren Sie den Schleifenkörper als Funktion, einen Functor oder ein Lambda mit Boost- oder C++ 0x-Funktionen? Ich persönlich mache mir lieber Gedanken darüber, wie eine zufällige for/while-Schleife implementiert oder gelesen wird.

3
Jason Govig

Wenn Sie häufig andere Algorithmen aus der STL verwenden, bietet for_each mehrere Vorteile:

  1. Sie ist oft einfacher und weniger fehleranfällig als eine for-Schleife, zum Teil weil Sie mit dieser Schnittstelle an Funktionen gewöhnt sind und zum Teil, weil sie in vielen Fällen etwas prägnanter ist.
  2. Obwohl eine bereichsbasierte for-Schleife noch einfacher sein kann, ist sie weniger flexibel (wie von Adrian McCarthy festgestellt, sie durchläuft einen ganzen Container).
  3. Im Gegensatz zu einer herkömmlichen for-Schleife zwingt for_each Sie, Code zu schreiben, der für jeden Eingabe-Iterator geeignet ist. Auf diese Weise eingeschränkt zu sein, kann eigentlich eine gute Sache sein, weil:

    1. Möglicherweise müssen Sie den Code später anpassen, damit er für einen anderen Container verwendet werden kann.
    2. Am Anfang könnte es Ihnen etwas beibringen und/oder Ihre Gewohnheiten zum Besseren verändern.
    3. Selbst wenn Sie immer für völlig gleichwertige Schleifen schreiben, tun dies möglicherweise andere Benutzer, die denselben Code ändern, ohne dass Sie dazu aufgefordert werden, for_each zu verwenden.
  4. Die Verwendung von for_each macht es manchmal offensichtlicher, dass Sie eine spezifischere STL-Funktion verwenden können, um dasselbe zu tun. (Wie in Jerry Coffins Beispiel; for_each ist nicht unbedingt die beste Option, aber eine for-Schleife ist nicht die einzige Alternative.)

2

Mit C++ 11 und zwei einfachen Vorlagen können Sie schreiben

        for ( auto x: range(v1+4,v1+6) ) {
                x*=2;
                cout<< x <<' ';
        }

als Ersatz für for_each oder eine Schleife. Wenn Sie sich für die Abkürzung und Sicherheit entscheiden, besteht kein Fehler in einem Ausdruck, der nicht vorhanden ist.

Für mich war for_each aus den gleichen Gründen immer besser, wenn der Schleifenkörper bereits ein Functor ist, und ich werde jeden Vorteil nutzen, den ich bekommen kann.

Sie verwenden immer noch den Drei-Ausdruck for, aber jetzt, wenn Sie einen sehen, wissen Sie, dass dort etwas zu verstehen ist, ist es keine Zwischenablage. Ich hasse boilerplate. Ich ärgere mich über seine Existenz. Es ist kein echter Code, durch das Lesen kann man nichts lernen, es ist nur eine weitere Sache, die überprüft werden muss. Die mentale Anstrengung kann daran gemessen werden, wie einfach es ist, bei der Überprüfung zu rosten.

Die Vorlagen sind

template<typename iter>
struct range_ { 
                iter begin() {return __beg;}    iter end(){return __end;}
            range_(iter const&beg,iter const&end) : __beg(beg),__end(end) {}
            iter __beg, __end;
};

template<typename iter>
range_<iter> range(iter const &begin, iter const &end)
    { return range_<iter>(begin,end); }
2
jthill

for ist für eine Schleife, die jedes Element oder jedes dritte Element iterieren kann. for_each dient nur zum Durchlaufen jedes Elements. Es ist aus dem Namen ersichtlich. Es ist also klarer, was Sie in Ihrem Code vorhaben.

Meistens musst du durchlaufen die gesamte Sammlung. Daher schlage ich vor, dass Sie Ihre eigene for_each () - Variante schreiben und dabei nur 2 Parameter verwenden. Damit können Sie das Beispiel von Terry Mahaffey wie folgt umschreiben:

for_each(container, [](int& i) {
    i += 10;
});

Ich denke, das ist in der Tat besser lesbar als eine for-Schleife. Dies erfordert jedoch die C++ 0x-Compiler-Erweiterungen.

1
Dimitri C.

Ich finde, dass for_each für die Lesbarkeit schlecht ist. Das Konzept ist gut, aber mit C++ ist es sehr schwer lesbar zu schreiben, zumindest für mich. C++ 0x-Lamda-Ausdrücke helfen dabei. Ich mag die Idee von Lamdas wirklich sehr. Auf den ersten Blick finde ich die Syntax jedoch sehr hässlich und ich bin nicht 100% ig sicher, dass ich mich jemals daran gewöhnen werde. Vielleicht habe ich mich in 5 Jahren daran gewöhnt und nicht weiter darüber nachgedacht, aber vielleicht auch nicht. Wir werden sehen :)

Ich bevorzuge es zu benutzen

vector<thing>::iterator istart = container.begin();
vector<thing>::iterator iend = container.end();
for(vector<thing>::iterator i = istart; i != iend; ++i) {
  // Do stuff
}

Ich finde eine explizite for-Schleife, die klarer zu lesen ist, und die Verwendung benannter Variablen für die Start- und End-Iteratoren, um das Durcheinander in der for-Schleife zu reduzieren.

Natürlich variieren die Fälle, das finde ich normalerweise am besten.

1
jcoder

for_each erlaubt die Implementierung von Fork-Join-Pattern . Ansonsten unterstützt sie fließend-Schnittstelle

gabelverbindungsmuster

Wir können die Implementierung gpu::for_each hinzufügen, um cuda/gpu für heterogenes paralleles Rechnen zu verwenden, indem Sie die Lambda-Task in mehreren Workern aufrufen.

gpu::for_each(users.begin(),users.end(),update_summary);
// all summary is complete now
// go access the user-summary here.

Und gpu::for_each kann warten, bis die Arbeiter alle Lambda-Aufgaben erledigt haben, bevor sie die nächsten Anweisungen ausführen.

fließende Schnittstelle

Es erlaubt uns, menschlich lesbaren Code auf kurze Art und Weise zu schreiben.

accounts::erase(std::remove_if(accounts.begin(),accounts.end(),used_this_year));
std::for_each(accounts.begin(),accounts.end(),mark_dormant);
0
shuva

Denn Schleife kann brechen; Ich möchte kein Papagei für Herb Sutter sein, also hier der Link zu seiner Präsentation: http://channel9.msdn.com/Events/BUILD/BUILD2011/TOOL-835T Bitte lesen Sie auch die Kommentare :)

0
NoSenseEtAl

Der Iterator kann ein Aufruf einer Funktion sein, die bei jeder Iteration durch die Schleife ausgeführt wird.

Siehe hier: http://www.cplusplus.com/reference/algorithm/for_each/

0
sdornan