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?
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.
Tags und Links c++ qt qtcore foreach containers