假设我们有一个结构,用于保存 3 个带有一些成员函数的双精度数:
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;
}
// ...
};
为了简单起见,这有点做作,但我相信你同意类似的代码在那里。这些方法允许您方便地链接,例如:
Vector v = ...;
v.normalize().negate();
甚至:
Vector v = Vector{1., 2., 3.}.normalize().negate();
现在,如果我们提供 begin() 和 end() 函数,我们可以在新样式的 for 循环中使用我们的 Vector,比如循环 3 个坐标 x、y 和 z(毫无疑问,您可以构建更多“有用”的示例通过用例如字符串替换向量):
Vector v = ...;
for (double x : v) { ... }
我们甚至可以这样做:
Vector v = ...;
for (double x : v.normalize().negate()) { ... }
并且:
for (double x : Vector{1., 2., 3.}) { ... }
但是,以下(在我看来)被破坏了:
for (double x : Vector{1., 2., 3.}.normalize()) { ... }
虽然它看起来像是前两种用法的逻辑组合,但我认为最后一种用法会产生一个悬空引用,而前两种用法完全没问题。
- 这是正确的并受到广泛赞赏吗?
- 以上哪一部分是“坏”的部分,应该避免?
- 是否可以通过更改基于范围的 for 循环的定义来改进语言,以便在 for 表达式中构造的临时对象在循环期间存在?