Wie kann ich verhindern, dass ich "for" - Schleifen mit einer "if" - Bedingung innerhalb mit C++?

Mit fast allen code, den ich Schreibe, bin ich oft Umgang mit set Reduzierung der Probleme, die auf Sammlungen, die letztendlich mit naiven "wenn" - Bedingungen im inneren von Ihnen. Hier ein einfaches Beispiel:

for(int i=0; i<myCollection.size(); i++)
{
     if (myCollection[i] == SOMETHING)
     {
           DoStuff();
     }
}

Mit funktionalen Sprachen, und ich habe das problem lösen können durch die Reduzierung der Sammlung zu einer anderen Sammlung (leicht) und dann alle Vorgänge in meinem reduzierten Satz. In pseudocode:

newCollection <- myCollection where <x=true
map DoStuff newCollection

Und in anderen C-Varianten, wie z.B. C#, könnte ich reduzieren, mit einer where-Klausel wie

foreach (var x in myCollection.Where(c=> c == SOMETHING)) 
{
   DoStuff();
}

Oder besser (zumindest für meine Augen)

myCollection.Where(c=>c == Something).ToList().ForEach(d=> DoStuff(d));

Zugegeben, ich bin dabei eine Menge von Paradigma mischen und subjektive/Meinung basiert Stil, aber ich kann mir nicht helfen, aber das Gefühl, dass mir etwas fehlt wirklich wichtig, könnte mir erlauben, verwenden Sie diese bevorzugte Technik mit C++. Könnte jemand mich aufklären?

  • Aus der C++ standard-library-Funktionen, können Sie versuchen std::copy_if sein, aber die Auswahl nicht faul
  • wenn es ok ist für Sie, eine Kopie zu machen, möchten Sie vielleicht werfen Sie einen Blick auf std::copy_if
  • Sie können daran interessiert sein, Reihe-v3. Sollte es auch dann kommen, um C++ als TS und hoffentlich standardisierte in einer zukünftigen Version.
  • c++11 hat lambda-Ausdrücke, so dass möglicherweise etwas, das Sie möchten, um zu sehen wie auch.
  • Ich schlage vor, Sie ändern den Titel, weil beide Antworten verwendet, die Schleifen
  • Könnte Sie klären, ob Sie interessiert sind, indem Sie die performance-Aspekte, oder allein durch die syntaktischen Aspekte?
  • Soweit ich weiß, dass C# - code wird nicht kompiliert. : ersetzt werden durch in
  • Hinzufügen @NullException Kommentar, der andere C# - snippet auch nicht kompilieren, weil es bewusst keine ForEach im IEnumerable
  • Ich fühle die Notwendigkeit zu betonen, dass der if innerhalb einer for Sie erwähnen, ist nicht nur ziemlich funktional gleichwertig zu den anderen Beispielen würde aber auch wahrscheinlich schneller in eine Menge von Fällen. Auch für jemanden, der behauptet, wie funktionalen Stil, was Sie fördern scheint zu gehen gegen die funktionale Programmierung das Geliebte Konzept von Reinheit, da DoStuff hat eindeutig side effcets.
  • Wenn Sie das tun, viele, viele Male mit den gleichen filter-Bedingungen, die ich vorschlagen würde, mit so etwas wie Boost multi_index, die pflegen können viele Indizes auf die gleichen Daten. Es ist wie mit Ihrem eigenen DB in der app.
  • Wenn Sie können, ich denke, man kann Sortieren Sie Ihre Daten zu ersetzen, der für"+", wenn mit nur einer for-Schleife iteriert über die Individuen, die hinsichtlich Ihrer Bedingungen (oder zwei Schleifen im Falle eines anderen, und so weiter)
  • Ich habe nie wirklich verstanden, warum die Menschen verbinden, die alle Logik auf einer einzigen Zeile macht es sich irgendwie besser oder mehr lesbar. C++ - snippet an der Spitze ist bei weitem die meisten lesbar für mich aus all Ihre Möglichkeiten. Und da der Wirkungsgrad nicht verändert wird, kann ich nicht verstehen, warum Sie lieber nicht zu schreiben, dass, es sei denn, Sie werden bezahlt nach der Anzahl der code-Zeilen, die Sie löschen.
  • Ich, die zweite. Ich denke, die for-Schleife mit der internen, wenn die mit Abstand am meisten lesbar. Ich bin mir nicht sicher über die Effizienz, mit der Ausnahme, dass es wohl wirklich schließen. Immer eine Untergruppe und dann die Iteration auf die Teilmenge der logisch erfordert zwei traversalen statt, und es ist immer noch der test für jedes element, so dass ich lieber zu durchqueren es einmal und explizit zeigen die Tests, dass das passieren wird sowieso für jedes element. Es ist (gerade noch) effizienter als die Art und Weise, und sehr viel transparenter.
  • Vereinbart: es ist nur syntaktischer Zucker. Und die Frage, der Titel ist irreführend, denn es ist sehr unterschiedlich zu vermeiden Verzweigung und versteckt es unter Abstraktion.
  • Heute ist die Effizienz nicht geändert. Morgen - vielleicht. Wenn Sie " Anforderungsfilterung ersten, dann einen Bereich für dann - ich bin, darüber zu spekulieren, hier - filtern könnten parallel ausgeführt werden (je nach Bibliothek) und könnte schneller sein (je nach Architektur). Wissen wir nicht - aber wir wollen nicht ausschließen.
  • Ein Vorteil in der Verwendung von Dingen wie map/filter zu iterieren über Sammlungen ist, dass Sie wissen, was Sie tun werden. Eine generische Schleife tun können, alle Arten von komplexen Zeug und es ist viel einfacher, auf die Einführung eines bug manuell schreiben der for Schleife als schreiben map doStuff collection. Dies kann auch helfen, den compiler bei der Optimierung. Das gleiche (mehr) wahr schreiben Sie die rekursive Funktion, die per hand oder mit so etwas wie einem fold/reduce statt.
  • Ich bin überrascht, dass niemand darauf hingewiesen, dass boost bedeutet dies: coliru.stacked-crooked.com/a/f2274ee265d19a1a
  • Wenn der compiler bekommt ausreichend schlau, dass er die erstaunliche Optimierungen, die Sie sich ausdenken, @lorro, sollte es sicherlich schlau genug, zu erkennen, gemeinsame Muster und transformieren Sie Sie so ausführen kann, dass es die gleichen Optimierungen. Die machen es wichtiger, code zu schreiben, in der normalen, offensichtlichen Weg. Vorausgesetzt natürlich, dass alle diese Optimierungen sind auch möglich, da Sie sehr wahrscheinlich brechen Bestellung von Sicherheiten, die durch die language-Spezifikation.
  • Ich Rede nicht von dem compiler, ich Rede von der Bibliothek, die filter(). Wir sind auf Vereinbarung, dass Sie nicht-trivial für einen compiler (und es ist nicht trivial, ob das getan werden sollte, in den ersten Platz), jedoch mit std::async() es ist jetzt fast trivial zu schreiben filter() hat, der die Filterung im hintergrund (klar, die Angabe dieser in der Dokumentation). Solange beide Ihren filter und loop-Körper sind ausreichend lang und können parallel ausgeführt werden, könnte dies beschleunigen Sie Ihren code ein wenig Recht.
  • es ist nicht unbedingt über code-Zeilen, ist es auch egal, ob Sie lieber in Operationen auf einem Bereich, oder lieber eine Schleife über einen Bereich, der explizit die Durchführung der gleichwertige operation auf jedes element. Auch ohne die bedingte, und noch bevor der range-basierte for-Schleifen, einige Leute immer noch nicht std::for_each wenn Sie hatte eine Pistole an Ihren Kopf, auf der Grundlage, dass die Schleife mehr lesbar sind, um Sie in allen Fällen. In der Erwägung, dass anderen Menschen gefallen for_each so viel, dass Sie standardisierte it 😉
  • Wie der OP sagt, der Wunsch, zu entfernen die explizite if folgt aus einem funktionalen Stil, c.f. degoes.net/articles/destroy-all-ifs
  • Möglich, Duplikat der Wie kombiniert man eine Funktion und ein Prädikat in for_each?

InformationsquelleAutor Darkenor | 2016-07-15
Schreibe einen Kommentar