Imaginemos que tenemos una estructura para contener 3 dobles con algunas funciones miembro:
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;
}
// ...
};
Esto es un poco artificial para simplificar, pero estoy seguro de que está de acuerdo en que existe un código similar. Los métodos le permiten encadenar convenientemente, por ejemplo:
Vector v = ...;
v.normalize().negate();
O incluso:
Vector v = Vector{1., 2., 3.}.normalize().negate();
Ahora, si proporcionamos las funciones begin () y end (), podríamos usar nuestro Vector en un bucle for de nuevo estilo, digamos para recorrer las 3 coordenadas x, y y z (sin duda puede construir más ejemplos "útiles" reemplazando Vector con, por ejemplo, String):
Vector v = ...;
for (double x : v) { ... }
Incluso podemos hacer:
Vector v = ...;
for (double x : v.normalize().negate()) { ... }
y también:
for (double x : Vector{1., 2., 3.}) { ... }
Sin embargo, lo siguiente (me parece a mí) está roto:
for (double x : Vector{1., 2., 3.}.normalize()) { ... }
Si bien parece una combinación lógica de los dos usos anteriores, creo que este último uso crea una referencia colgante, mientras que los dos anteriores están completamente bien.
- ¿Es esto correcto y ampliamente apreciado?
- ¿Qué parte de lo anterior es la parte "mala" que debe evitarse?
- ¿Se mejoraría el lenguaje cambiando la definición del bucle for basado en el rango de modo que los temporales construidos en la expresión for existan durante la duración del bucle?