Warum erstellt Qt foreach eine Kopie des Containers?

8

Die Dokumentation sagt einfach , dass es tut , tut aber nicht t erklären warum:

  

Qt nimmt automatisch eine Kopie des Containers, wenn er eingeht   foreach Schleife. Wenn Sie den Container beim Iterieren ändern, dann   wird die Schleife nicht beeinflussen. (Wenn Sie den Container nicht ändern, die Kopie   immer noch stattfindet, aber dank implizitem Teilen einen Container kopieren   ist sehr schnell.) Da foreach erstellt eine Kopie des Containers, mit a   Nicht-const Referenz für die Variable können Sie nicht ändern   Originalbehälter. Es betrifft nur die Kopie, die es wahrscheinlich nicht ist   was du willst.

Für mich sieht das wie ein selbst auferlegtes Handicap aus, das Qt foreach weniger nützlich macht, als es hätte sein können - jetzt können Sie es nicht benutzen, um Elemente zu modifizieren.

Ich habe gehört, dass Boost foreach und das neue C ++ 11 for (auto iter : array) keine Kopie ausführen (obwohl ich mit keinem davon vertraut bin).

Was ist der Grund für dieses Kopieren?

    
sashoalm 12.05.2014, 15:19
quelle

1 Antwort

5

Die Qt-Entwickler haben sich für den Anwendungsfall entschieden, der Überraschungen verhindern soll, wenn Sie den Container in der Schleife ändern (wie in einem Signal-Handler, einem .k. a. Slot usw.), ohne den ursprünglichen Container zu verändern.

Es könnte schwierig sein, mit dem Signal-Slot-Mechanismus herauszufinden, ob etwas geändert wurde. Es wäre grundsätzlich Sache des Steckplatzes, wenn Sie das Signal mit diesem Container-Glied ausgeben. Natürlich müssten Sie die externe Kopie immer machen, sonst.

Ein weiterer Vorteil besteht darin, dass Sie einen Methodenaufruf an den zweiten Parameter ohne kontinuierliche Neuauswertung übergeben können, da die Kopie das erste Mal erstellt wird. Dies ist eigentlich ein nettes Feature, wenn Sie mich fragen, denn oft möchten Sie über die assoziierten Array-Schlüssel oder Werte wie myHash.keys() oder myHash.values() iterieren.

Man könnte argumentieren, dass der Boost auch einen Signal-Slot-Mechanismus hat. Ja, es ist meiner Meinung nach nur ein anderer Weg. Sie müssen nicht immer dasselbe tun. : -)

Unterschiedliche Leute haben einen anderen Geschmack bezüglich API, Styling und so weiter. Schließlich haben Sie alle Werkzeuge in der Hand, um den Anwendungsfall zu erreichen, mit dem Sie arbeiten möchten.

Sie könnten auch argumentieren, dass es nicht das ist, was Sie wollen und Sie würden stattdessen eine explizite Kopie machen. Das ist fair genug, man kann mit Boost oder dem Standard foreach in C ++ so weit gehen.

Es gibt hier keine Leistungsbedenken mit der Kopie, da für normale Iteration ohne Modifikation die Kopie-beim-Schreiben (a. k. a. implizite Freigabe) gut genug ist. Es hat einige Performance-Overhead, aber es ist vernachlässigbar.

Die richtige Qt-Semantik für einen solchen Anwendungsfall wäre die Verwendung des Iterator-Entwurfsmusters. Qt hat überall Iterator-Klassen, die zum Beispiel dem "Java-Stil" folgen.

    
lpapp 12.05.2014, 15:34
quelle

Tags und Links