Elegante Möglichkeit, in C ++ zu iterieren

7

Nehmen wir an, ich habe einen Vektor von Polygonen, wobei jedes Polygon einen Punktvektor enthält. Ich muss in meinem Code viele Punkte aller Polygone durchlaufen, ich muss den gleichen Code immer wieder schreiben:

%Vor%

Ich habe wirklich das Gefühl, dass es viel Code für zwei einfache Iterationen gibt und dass es den Code verstopft und die Lesbarkeit beeinträchtigt.

Einige Optionen, die ich dachte, sind:

  • mit #defines - aber es würde nicht portierbar (in anderen Teilen des Codes zu verwenden). Außerdem werden #defines heutzutage als böse angesehen;
  • iterate über vector- & gt; size () - es scheint nicht der eleganteste Weg;
  • ruft eine Methode mit einem Funktionszeiger auf - aber in diesem Fall wäre der Code, der innerhalb der Schleife liegen sollte, weit von der Schleife entfernt.

Also, was wäre die sauberste und eleganteste Art, dies zu tun?

    
André Wagner 11.01.2013, 21:10
quelle

7 Antworten

24

In C ++ 11 verwenden Sie ranged-base für Loops und das Schlüsselwort auto :

%Vor%     
Robᵩ 11.01.2013, 21:14
quelle
9

Wenn Sie C ++ 11 nicht verwenden können, hat boost ein FOREACH Makro, das viel Code generiert, aber Ihren Code drastisch vereinfacht:

%Vor%     
pelletjl 11.01.2013 21:18
quelle
5

Wenn Sie C ++ 11 nicht verwenden können, geben Sie den Iterator-Typ möglicherweise etwas kürzer ein als

%Vor%     
src 11.01.2013 21:17
quelle
5

Die innere Schleife kann mit folgenden Algorithmen umgeschrieben werden:

%Vor%

Das Mischen mit der äußeren Schleife ist etwas komplexer:

%Vor%

Wenn wir einen zusammengesetzten Iterator hätten, könnten wir wirklich Ihre Absicht ausdrücken, etwas für jeden Punkt in jedem Polygon zu tun . Und eine Bereich -Bibliothek wie Boost.Range würde es Ihnen erlauben, jeden Container doppelt zu benennen, da Sie mit dem gesamten Bereich arbeiten möchten.

Meine ideale Version Ihres Codes würde folgendermaßen aussehen:

%Vor%

würde flatten eine Ansicht von jedem Point in jedem Polygon zurückgeben, als wäre es ein einzelner fortlaufender Bereich . Beachten Sie, dass dies in plain C ++ 03 erreicht werden kann, und alles, was wir in Boost.Range vermissen, ist ein erweiterter Bereich , was in Bezug auf den Bereich join nicht schwer zu implementieren sein sollte.

Andernfalls hilft Ihnen die bereichsbasierte for-Schleife zusammen mit auto , die Anzahl der Wiederholungen zu reduzieren und die komplizierten Typen zu vergessen.

    
K-ballo 11.01.2013 21:17
quelle
1

Sie brauchen eine Abstraktionsschicht. Schreiben Sie eine Klasse, die diesen Vektor verwaltet, statt mit einem Vektor von Polygonen umzugehen. Die Klasse stellt dann Iteratorpaare zum Iterieren über die Punkte bereit. Der Code im Iterator kennt und kapselt diese Details.

    
Pete Becker 11.01.2013 21:28
quelle
1

Vergesst nicht, das wird nicht funktionieren, da ihr einen Vektor von Zeigern auf der obersten Ebene habt, aber ich werde es weiter machen, weil ich denke, dass es ziemlich cool ist.

Meine Template-Metaprogrammierung ist ein wenig eingerostet, also könnte es einen einfacheren Weg dafür geben, aber:

%Vor%

Für Ihren Fall können Sie es so verwenden (nein, Sie können nicht):

%Vor%     
Benjamin Lindley 11.01.2013 21:28
quelle
0

Zuallererst gibt es die einfache alte, auf Ganzzahlen basierende Schleife. Ein bisschen kürzer als Iteratoren.

%Vor%

Wenn Sie das nicht mögen und C ++ 11 nicht verfügbar ist, können Sie eine Funktion schreiben, die einen Funktor akzeptiert (diese waren in C ++ 0x unter std::tr1 Ich glaube):

%Vor%

Alternativ ein einfaches altes Makro:

%Vor%     
bobobobo 11.01.2013 21:37
quelle

Tags und Links