Hãy tưởng tượng chúng ta có một cấu trúc để giữ 3 bộ đôi với một số hàm thành viên:
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;
}
// ...
};
Điều này hơi giả tạo vì sự đơn giản, nhưng tôi chắc chắn rằng bạn đồng ý rằng mã tương tự hiện có. Các phương pháp cho phép bạn xâu chuỗi một cách thuận tiện, ví dụ:
Vector v = ...;
v.normalize().negate();
Hoặc thậm chí:
Vector v = Vector{1., 2., 3.}.normalize().negate();
Bây giờ nếu chúng tôi cung cấp các hàm begin () và end (), chúng tôi có thể sử dụng Vector của mình trong một vòng lặp for kiểu mới, chẳng hạn như lặp qua 3 tọa độ x, y và z (chắc chắn bạn có thể xây dựng các ví dụ "hữu ích" hơn bằng cách thay thế Vector bằng ví dụ: Chuỗi):
Vector v = ...;
for (double x : v) { ... }
Chúng tôi thậm chí có thể làm:
Vector v = ...;
for (double x : v.normalize().negate()) { ... }
và cả:
for (double x : Vector{1., 2., 3.}) { ... }
Tuy nhiên, điều sau (có vẻ như đối với tôi) đã bị hỏng:
for (double x : Vector{1., 2., 3.}.normalize()) { ... }
Mặc dù nó có vẻ như là một sự kết hợp hợp lý của hai cách sử dụng trước, tôi nghĩ cách sử dụng cuối cùng này tạo ra một tham chiếu lơ lửng trong khi hai cách sử dụng trước đó hoàn toàn ổn.
- Điều này có chính xác và được đánh giá cao không?
- Phần nào trên đây là phần "xấu", cần tránh?
- Liệu ngôn ngữ có được cải thiện bằng cách thay đổi định nghĩa của vòng lặp for dựa trên phạm vi để các dấu tạm thời được xây dựng trong biểu thức for tồn tại trong suốt thời gian của vòng lặp không?