Stellen wir uns vor, wir haben eine Struktur für 3 Doubles mit einigen Mitgliedsfunktionen:
struct Vector {
double x, y, z;
// ...
Vector &negate() {
x = -x; y = -y; z = -z;
return *this;
}
Vector &normalize() {
double s = 1./sqrt(x*x+y*y+z*z);
x *= s; y *= s; z *= s;
return *this;
}
// ...
};
Dies ist der Einfachheit halber ein wenig erfunden, aber ich bin sicher, Sie stimmen zu, dass es ähnlichen Code gibt. Mit den Methoden können Sie bequem verketten, zum Beispiel:
Vector v = ...;
v.normalize().negate();
Oder auch:
Vector v = Vector{1., 2., 3.}.normalize().negate();
Wenn wir nun die Funktionen begin () und end () bereitstellen, könnten wir unseren Vektor in einer neuen for-Schleife verwenden, beispielsweise um die 3 Koordinaten x, y und z zu durchlaufen (Sie können zweifellos weitere "nützliche" Beispiele erstellen durch Ersetzen von Vector durch zB String):
Vector v = ...;
for (double x : v) { ... }
Wir können sogar:
Vector v = ...;
for (double x : v.normalize().negate()) { ... }
und auch:
for (double x : Vector{1., 2., 3.}) { ... }
Das Folgende (es scheint mir) ist jedoch kaputt:
for (double x : Vector{1., 2., 3.}.normalize()) { ... }
Während es wie eine logische Kombination der beiden vorherigen Verwendungen erscheint, denke ich, dass diese letzte Verwendung eine baumelnde Referenz erzeugt, während die vorherigen beiden völlig in Ordnung sind.
- Ist das richtig und weithin geschätzt?
- Welcher Teil des oben genannten ist der "schlechte" Teil, der vermieden werden sollte?
- Würde die Sprache verbessert, indem die Definition der bereichsbasierten for-Schleife so geändert wird, dass im for-Ausdruck konstruierte Temporäre für die Dauer der Schleife existieren?