Wyobraźmy sobie, że mamy strukturę do trzymania 3 podwójnych z niektórymi funkcjami składowymi:
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;
}
// ...
};
Jest to trochę wymyślone dla uproszczenia, ale jestem pewien, że zgadzasz się, że istnieje podobny kod. Metody te pozwalają wygodnie łączyć, na przykład:
Vector v = ...;
v.normalize().negate();
Lub nawet:
Vector v = Vector{1., 2., 3.}.normalize().negate();
Teraz, gdybyśmy zapewnili funkcje begin () i end (), moglibyśmy użyć naszego Vectora w nowej pętli for, powiedzmy aby wykonać pętlę po trzech współrzędnych x, y i z (bez wątpienia można skonstruować więcej "użytecznych" przykładów zastępując Vector np. String):
Vector v = ...;
for (double x : v) { ... }
Możemy nawet zrobić:
Vector v = ...;
for (double x : v.normalize().negate()) { ... }
i również:
for (double x : Vector{1., 2., 3.}) { ... }
Jednak następujący (wydaje mi się) jest uszkodzony:
for (double x : Vector{1., 2., 3.}.normalize()) { ... }
Chociaż wydaje się to logicznym połączeniem dwóch poprzednich zastosowań, myślę, że to ostatnie użycie tworzy zwisające odniesienie, podczas gdy poprzednie dwa są całkowicie w porządku.
- Czy jest to poprawne i powszechnie doceniane?
- Która część powyższego jest „złą” częścią, której należy unikać?
- Czy język zostałby ulepszony poprzez zmianę definicji pętli for opartej na zakresie, tak aby elementy tymczasowe skonstruowane w wyrażeniu for istniały przez cały czas trwania pętli?