1

acabo de subir una pregunta en la que exponía un problema que estaba teniendo a la hora de realizar la sobrecarga del operador suma (+) para poder operar con dos vectores. Un compañero ha conseguido descifrar el problema y brindarme la solución: El problema residía en que se estaba tratando de acceder a un lvalue cuando correspondía un rvalue. La solución era bien sencilla y consistía en añadir a la declaración del método la palabra reservada const en el argumento que le pasaba como referencia:

Vector2D operator +(const Vector2D& v);

Abro esta respuesta porque no acabo de entender por qué al añadir el const se soluciona el problema. Si alguien puede realizar una breve explicación o indicarme algún foro o página se lo agradecería :)

1 Answers1

2

Falta indicar que la pregunta original es esta.

Aprovechando el ejemplo de la respuesta a esa pregunta:

struct Vector2D {
  Vector2D operator+( Vector2D & ) { return Vector2D( ); }
  Vector2D operator*( int ) { return Vector2D( ); }
};

int main( ) {
  Vector2D position;
  Vector2D speed;

  auto result = position + speed * 4;

  return 0;
}

La operación conflictiva es esta:

auto result = position + speed * 4;

Y el problema que tenemos aquí es que esta operación es compleja, por lo que necesitamos descomponerla:

auto temp = speed * 4;
auto result = position + temp;

Vale, como puedes observar, temp es un objeto que se crea implícitamente y, por tanto, no se asigna a una variable en concreto. El caso es que este resultado temporal no se asigna a una variable.

Este detalle es importante ya que, al no usar una variable para almacenar este valor, el mismo pasa a ser consierado como un r-value y una característica de los r-value es que son constantes.

Dado que el objeto es constante, al realizar la suma, el compilador intentará localizar una sobrecarga en la que el parámetro sea constante... no la encuentra y la compilación falla.

Puedes probar a dividir la operación, como he hecho yo en esta respuesta, y verás como entonces sí que funciona con la versión no const

eferion
  • 49,291
  • 5
  • 30
  • 72
  • Aaahhhh vale, ya entiendo. Pues muchas gracias por tomarte la molestia de explicarlo (y perdona por no haber puesto el enlace a la anterior pregunta que menciono jeje) – Diego Martinez Apr 20 '20 at 12:47
  • @Trauma es un _r-value_ luego se equipara a un literal, por ejemplo `5`. ¿Te parecería lógico poder modificar un `5` en esta expresión: `x=n+5`? Es lógico pensar que ese `5` se debe recibir como un parámetro constante, o eso o bajo la sintaxis de movimiento, pero no sería válida una referencia no constante – eferion Apr 20 '20 at 16:47
  • 1
    @Trauma para este caso tenemos _r-value_ y _l-value_. El primero debes referenciarlo de forma constante mientras que en el segundo caso esa obligación no existe... al compilador le da igual que sea un objeto temporal... es un _r-value_ y le aplica las reglas correspondientes – eferion Apr 20 '20 at 16:51
  • 1
    @Trauma Son const porque su modificación no tiene sentido. Son objetos que van a dejar de existir en cuanto la instrucción actual finalice. Sin esta restricción necesitarías un tipo _r-value_ para literales y otro para objetos temporales... ¿o hacemos que los literales también se puedan modificar? Total, solo hay que meterlos en una variable... al final es un coste que no se asume en C++... cuya irónica filosofía es "_no pagues por lo que no usas_" – eferion Apr 20 '20 at 16:55
  • 1
    @Trauma las limitaciones son importantes ya que hacen que un producto exista... no existe un material que trabaje bien a cualquier temperatura ni un soporte que aguante cualquier peso... cualquier objeto, para ser real, está sujeto a restricciones y son esas restricciones las que le permiten existir. En programación pasa algo parecido... sin limitaciones no sería posible programar o, sería algo infernal... aparte que programar los compiladores sería una tarea titánica. Las restricciones son normas o reglas y lo que nos toca es ajustarnos a ellas... aunque a veces no las entendamos – eferion Apr 20 '20 at 17:24
  • jejeje ... pero me gusta saber **el motivo**. Soy muy *fiki* :-D – Trauma Apr 20 '20 at 17:28